This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 2.x development tree".
The branch, seventeen has been updated via b3f5e2b2a9153bf4a55c79f44d8a983487f7b55c (commit) from a158cbbb1d0dd36bc02e48df18be3d7cf47d8013 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit b3f5e2b2a9153bf4a55c79f44d8a983487f7b55c Author: Arne Fitzenreiter arne_f@ipfire.org Date: Sun Nov 30 01:45:15 2014 +0100
remove more enused patches.
-----------------------------------------------------------------------
Summary of changes: lfs/cyrus-imapd | 1 - lfs/udev | 1 - .../Pound-2.6-reneg-ciphers-altnames-nosslv2.patch | 452 - ...mpat-drivers-3.8-1-u-kref_get_unless_zero.patch | 38 - .../compat-wireless-2.6.34-usbnet_compile.patch | 28 - .../compat-wireless-2.6.39_kfifo_module_info.patch | 14 - ...at-wireless-3.5-build_ath5k_only_with_pci.patch | 16 - src/patches/compat-wireless-3.5-libertas_uap.patch | 5080 ------ ...t-wireless_codel-avoid-a-nul-rec_inv_sqrt.patch | 68 - src/patches/dhcp-3.1_linux3.patch | 11 - src/patches/glibc-arm-dont-use-swp.patch | 305 - src/patches/grub-gentoo-14.patch | 16087 ------------------- src/patches/lcd4linux-scaletext-dpf.patch | 59 - src/patches/libcap-1.10-shared.patch | 18 - src/patches/libcap-1.10-syscall.patch | 43 - src/patches/libnl-1.1-ULONG_MAX.patch | 11 - src/patches/libsigc++-gcc43.patch | 85 - src/patches/lzo-2.06-CVE-2014-4607.patch | 0 src/patches/nasm-0.98.39-security_fix-1.patch | 21 - src/patches/net-tools-1.60-kernel_headers-2.patch | 51 - src/patches/netfilter_layer7_2.22_kernel3.0.patch | 2160 --- src/patches/openssl-0.9.8n-cryptodev.diff | 99 - src/patches/pciutils-2.1.10-scan.patch | 12 - src/patches/pciutils-2.1.99-gcc4.patch | 17 - src/patches/pciutils-2.2.1-idpath.patch | 11 - src/patches/pciutils-2.2.3-multilib.patch | 130 - src/patches/pciutils-2.2.3-sata.patch | 11 - src/patches/pciutils-devicetype.patch | 136 - src/patches/pciutils-havepread.patch | 57 - src/patches/pciutils-strip.patch | 22 - src/patches/pound-2.6.patch | 11 - .../python-satsolver-only-python-bindings.patch | 27 - .../python-satsover-fix-building-without-rpm.patch | 37 - src/patches/qemu-0.14.1_missing_ATFCWD_hack.patch | 28 - src/patches/r8101_add_missing_pciids.patch | 11 - src/patches/r8169_add_missing_pciids.patch | 17 - src/patches/sudo-1.6.8p12-envvar_fix-1.patch | 59 - src/patches/udev-125-ext4_wo_journal.patch | 50 - src/patches/udev-141_no_netif_rename.patch | 50 - src/patches/v4l-dvb_bestunar_us638x.patch | 2810 ---- src/patches/v4l-dvb_rtl28xx_add_usb_ids.patch | 14 - .../v4l-dvb_rtl28xx_commented_usb_clear_halt.patch | 12 - .../v4l-dvb_usbv2_dont_report_pidfilter_fail.patch | 16 - src/patches/vdr-1.6.0-gcc44-fixes.patch | 62 - src/patches/vdr-plugin-epgsearch-gcc44.patch | 78 - 45 files changed, 28326 deletions(-) delete mode 100644 src/patches/Pound-2.6-reneg-ciphers-altnames-nosslv2.patch delete mode 100644 src/patches/compat-drivers-3.8-1-u-kref_get_unless_zero.patch delete mode 100644 src/patches/compat-wireless-2.6.34-usbnet_compile.patch delete mode 100644 src/patches/compat-wireless-2.6.39_kfifo_module_info.patch delete mode 100644 src/patches/compat-wireless-3.5-build_ath5k_only_with_pci.patch delete mode 100644 src/patches/compat-wireless-3.5-libertas_uap.patch delete mode 100644 src/patches/compat-wireless_codel-avoid-a-nul-rec_inv_sqrt.patch delete mode 100644 src/patches/dhcp-3.1_linux3.patch delete mode 100644 src/patches/glibc-arm-dont-use-swp.patch delete mode 100644 src/patches/grub-gentoo-14.patch delete mode 100644 src/patches/lcd4linux-scaletext-dpf.patch delete mode 100644 src/patches/libcap-1.10-shared.patch delete mode 100644 src/patches/libcap-1.10-syscall.patch delete mode 100644 src/patches/libnl-1.1-ULONG_MAX.patch delete mode 100644 src/patches/libsigc++-gcc43.patch mode change 100755 => 100644 src/patches/lzo-2.06-CVE-2014-4607.patch delete mode 100644 src/patches/nasm-0.98.39-security_fix-1.patch delete mode 100644 src/patches/net-tools-1.60-kernel_headers-2.patch delete mode 100644 src/patches/netfilter_layer7_2.22_kernel3.0.patch delete mode 100644 src/patches/openssl-0.9.8n-cryptodev.diff delete mode 100644 src/patches/pciutils-2.1.10-scan.patch delete mode 100644 src/patches/pciutils-2.1.99-gcc4.patch delete mode 100644 src/patches/pciutils-2.2.1-idpath.patch delete mode 100644 src/patches/pciutils-2.2.3-multilib.patch delete mode 100644 src/patches/pciutils-2.2.3-sata.patch delete mode 100644 src/patches/pciutils-devicetype.patch delete mode 100644 src/patches/pciutils-havepread.patch delete mode 100644 src/patches/pciutils-strip.patch delete mode 100644 src/patches/pound-2.6.patch delete mode 100644 src/patches/python-satsolver-only-python-bindings.patch delete mode 100644 src/patches/python-satsover-fix-building-without-rpm.patch delete mode 100644 src/patches/qemu-0.14.1_missing_ATFCWD_hack.patch delete mode 100644 src/patches/r8101_add_missing_pciids.patch delete mode 100644 src/patches/r8169_add_missing_pciids.patch delete mode 100644 src/patches/sudo-1.6.8p12-envvar_fix-1.patch delete mode 100644 src/patches/udev-125-ext4_wo_journal.patch delete mode 100644 src/patches/udev-141_no_netif_rename.patch delete mode 100644 src/patches/v4l-dvb_bestunar_us638x.patch delete mode 100644 src/patches/v4l-dvb_rtl28xx_add_usb_ids.patch delete mode 100644 src/patches/v4l-dvb_rtl28xx_commented_usb_clear_halt.patch delete mode 100644 src/patches/v4l-dvb_usbv2_dont_report_pidfilter_fail.patch delete mode 100644 src/patches/vdr-1.6.0-gcc44-fixes.patch delete mode 100644 src/patches/vdr-plugin-epgsearch-gcc44.patch
Difference in files: diff --git a/lfs/cyrus-imapd b/lfs/cyrus-imapd index 8f74c5a..2a826cd 100644 --- a/lfs/cyrus-imapd +++ b/lfs/cyrus-imapd @@ -79,7 +79,6 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE) cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/cyrus-imapd-2.2.12-autocreate-0.9.4.diff cd $(DIR_APP) && patch -Np0 < $(DIR_SRC)/src/patches/cyrus-imapd-2.2.12-gcc4.patch -# cp -f /usr/include/et/com_err.h /usr/include/com_err.h cd $(DIR_APP) && ./configure --prefix=/usr --with-service-path=/usr/lib/cyrus \ --with-cyrus-prefix=/usr/lib/cyrus --sysconfdir=/var/ipfire/cyrusimap \ --with-auth=unix --with-perl --with-sasl --with-idle=idled \ diff --git a/lfs/udev b/lfs/udev index fdf8bf2..15dae81 100644 --- a/lfs/udev +++ b/lfs/udev @@ -76,7 +76,6 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) cd $(DIR_APP) && tar axf $(DIR_DL)/udev-lfs-$(VER)-1.tar.bz2
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/udev-208_remove_systemd_log.patch -# cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/udev-141_no_netif_rename.patch
cd $(DIR_APP)/udev-lfs-$(VER)-1 && sed -i "s/HANDLE_AT 1/HANDLE_AT 0/g" cfg.h
diff --git a/src/patches/Pound-2.6-reneg-ciphers-altnames-nosslv2.patch b/src/patches/Pound-2.6-reneg-ciphers-altnames-nosslv2.patch deleted file mode 100644 index 9c874c8..0000000 --- a/src/patches/Pound-2.6-reneg-ciphers-altnames-nosslv2.patch +++ /dev/null @@ -1,452 +0,0 @@ -diff -Naur Pound-2.6.orig/config.c Pound-2.6.reneg-ciphers-altnames-nosslv2/config.c ---- Pound-2.6.orig/config.c 2011-12-28 14:57:45.000000000 +0100 -+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/config.c 2012-02-15 21:49:39.000000000 +0100 -@@ -31,6 +31,8 @@ - - #include "pound.h" - -+#include <openssl/x509v3.h> -+ - #ifdef MISS_FACILITYNAMES - - /* This is lifted verbatim from the Linux sys/syslog.h */ -@@ -76,7 +78,7 @@ - static regex_t Err414, Err500, Err501, Err503, MaxRequest, HeadRemove, RewriteLocation, RewriteDestination; - static regex_t Service, ServiceName, URL, HeadRequire, HeadDeny, BackEnd, Emergency, Priority, HAport, HAportAddr; - static regex_t Redirect, RedirectN, TimeOut, Session, Type, TTL, ID, DynScale; --static regex_t ClientCert, AddHeader, Ciphers, CAlist, VerifyList, CRLlist, NoHTTPS11; -+static regex_t ClientCert, AddHeader, DisableSSLv2, SSLAllowClientRenegotiation, SSLHonorCipherOrder, Ciphers, CAlist, VerifyList, CRLlist, NoHTTPS11; - static regex_t Grace, Include, ConnTO, IgnoreCase, HTTPS, HTTPSCert, Disabled, Threads, CNName; - - static regmatch_t matches[5]; -@@ -167,6 +169,53 @@ - } - } - -+unsigned char ** -+get_subjectaltnames(X509 *x509, unsigned int *count) -+{ -+ *count = 0; -+ unsigned int local_count = 0; -+ unsigned char **result = NULL; -+ -+ STACK_OF(GENERAL_NAME) *san_stack = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL); -+ -+ unsigned char *temp[sk_GENERAL_NAME_num(san_stack)]; -+ -+ GENERAL_NAME *name = NULL; -+ while(sk_GENERAL_NAME_num(san_stack) > 0) -+ { -+ name = sk_GENERAL_NAME_pop(san_stack); -+ -+ switch(name->type) -+ { -+ case GEN_DNS: -+ temp[local_count] = strndup(ASN1_STRING_data(name->d.dNSName), ASN1_STRING_length(name->d.dNSName)+1); -+ if(temp[local_count] == NULL) { conf_err("out of memory"); } -+ local_count++; -+ break; -+ default: -+ logmsg(LOG_INFO, "unsupported subjectAltName type encountered: %i", name->type); -+ } -+ -+ GENERAL_NAME_free(name); -+ } -+ -+ result = (unsigned char**)malloc(sizeof(unsigned char*)*local_count); -+ if(result == NULL) { conf_err("out of memory"); } -+ int i; -+ for(i = 0;i < local_count; i++) -+ { -+ result[i] = strndup(temp[i], strlen(temp[i])+1); -+ if(result[i] == NULL) { conf_err("out of memory"); } -+ -+ free(temp[i]); -+ } -+ *count = local_count; -+ -+ sk_GENERAL_NAME_pop_free(san_stack, GENERAL_NAME_free); -+ -+ return result; -+} -+ - /* - * parse a back-end - */ -@@ -289,9 +338,12 @@ - } else if(!regexec(&HTTPS, lin, 4, matches, 0)) { - if((res->ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) - conf_err("SSL_CTX_new failed - aborted"); -+ SSL_CTX_set_app_data(res->ctx, res); - SSL_CTX_set_verify(res->ctx, SSL_VERIFY_NONE, NULL); - SSL_CTX_set_mode(res->ctx, SSL_MODE_AUTO_RETRY); - SSL_CTX_set_options(res->ctx, SSL_OP_ALL); -+ SSL_CTX_clear_options(res->ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); -+ SSL_CTX_clear_options(res->ctx, SSL_OP_LEGACY_SERVER_CONNECT); - sprintf(lin, "%d-Pound-%ld", getpid(), random()); - SSL_CTX_set_session_id_context(res->ctx, (unsigned char *)lin, strlen(lin)); - SSL_CTX_set_tmp_rsa_callback(res->ctx, RSA_tmp_callback); -@@ -299,6 +351,7 @@ - } else if(!regexec(&HTTPSCert, lin, 4, matches, 0)) { - if((res->ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) - conf_err("SSL_CTX_new failed - aborted"); -+ SSL_CTX_set_app_data(res->ctx, res); - lin[matches[1].rm_eo] = '\0'; - if(SSL_CTX_use_certificate_chain_file(res->ctx, lin + matches[1].rm_so) != 1) - conf_err("SSL_CTX_use_certificate_chain_file failed - aborted"); -@@ -309,6 +362,8 @@ - SSL_CTX_set_verify(res->ctx, SSL_VERIFY_NONE, NULL); - SSL_CTX_set_mode(res->ctx, SSL_MODE_AUTO_RETRY); - SSL_CTX_set_options(res->ctx, SSL_OP_ALL); -+ SSL_CTX_clear_options(res->ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); -+ SSL_CTX_clear_options(res->ctx, SSL_OP_LEGACY_SERVER_CONNECT); - sprintf(lin, "%d-Pound-%ld", getpid(), random()); - SSL_CTX_set_session_id_context(res->ctx, (unsigned char *)lin, strlen(lin)); - SSL_CTX_set_tmp_rsa_callback(res->ctx, RSA_tmp_callback); -@@ -805,13 +860,23 @@ - /* logmsg(LOG_DEBUG, "Received SSL SNI Header for servername %s", servername); */ - - SSL_set_SSL_CTX(ssl, NULL); -- for(pc = ctx; pc; pc = pc->next) -+ for(pc = ctx; pc; pc = pc->next) { - if(fnmatch(pc->server_name, server_name, 0) == 0) { - /* logmsg(LOG_DEBUG, "Found cert for %s", servername); */ - SSL_set_SSL_CTX(ssl, pc->ctx); - return SSL_TLSEXT_ERR_OK; - } -- -+ else if(pc->subjectAltNameCount > 0 && pc->subjectAltNames != NULL) { -+ int i; -+ for(i = 0; i < pc->subjectAltNameCount; i++) { -+ if(fnmatch(pc->subjectAltNames[i], server_name, 0) == 0) { -+ SSL_set_SSL_CTX(ssl, pc->ctx); -+ return SSL_TLSEXT_ERR_OK; -+ } -+ } -+ } -+ } -+ - /* logmsg(LOG_DEBUG, "No match for %s, default used", server_name); */ - SSL_set_SSL_CTX(ssl, ctx->ctx); - return SSL_TLSEXT_ERR_OK; -@@ -829,11 +894,15 @@ - SERVICE *svc; - MATCHER *m; - int has_addr, has_port, has_other; -+ long ssl_op_enable, ssl_op_disable; - struct hostent *host; - struct sockaddr_in in; - struct sockaddr_in6 in6; - POUND_CTX *pc; - -+ ssl_op_enable = SSL_OP_ALL; -+ ssl_op_disable = SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | SSL_OP_LEGACY_SERVER_CONNECT; -+ - if((res = (LISTENER *)malloc(sizeof(LISTENER))) == NULL) - conf_err("ListenHTTPS config: out of memory - aborted"); - memset(res, 0, sizeof(LISTENER)); -@@ -844,6 +913,8 @@ - res->err500 = "An internal server error occurred. Please try again later."; - res->err501 = "This method may not be used."; - res->err503 = "The service is not available. Please try again later."; -+ res->allow_client_reneg = 0; -+ res->disable_ssl_v2 = 0; - res->log_level = log_level; - if(regcomp(&res->verb, xhttp[0], REG_ICASE | REG_NEWLINE | REG_EXTENDED)) - conf_err("xHTTP bad default pattern - aborted"); -@@ -959,6 +1030,9 @@ - fclose(fcert); - memset(server_name, '\0', MAXBUF); - X509_NAME_oneline(X509_get_subject_name(x509), server_name, MAXBUF - 1); -+ pc->subjectAltNameCount = 0; -+ pc->subjectAltNames = NULL; -+ pc->subjectAltNames = get_subjectaltnames(x509, &(pc->subjectAltNameCount)); - X509_free(x509); - if(!regexec(&CNName, server_name, 4, matches, 0)) { - server_name[matches[1].rm_eo] = '\0'; -@@ -1029,6 +1103,25 @@ - strcat(res->add_head, "\r\n"); - strcat(res->add_head, lin + matches[1].rm_so); - } -+ } else if(!regexec(&DisableSSLv2, lin, 4, matches, 0)) { -+ res->disable_ssl_v2 = 1; -+ } else if(!regexec(&SSLAllowClientRenegotiation, lin, 4, matches, 0)) { -+ res->allow_client_reneg = atoi(lin + matches[1].rm_so); -+ if (res->allow_client_reneg == 2) { -+ ssl_op_enable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; -+ ssl_op_disable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; -+ } else { -+ ssl_op_disable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; -+ ssl_op_enable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; -+ } -+ } else if(!regexec(&SSLHonorCipherOrder, lin, 4, matches, 0)) { -+ if (atoi(lin + matches[1].rm_so)) { -+ ssl_op_enable |= SSL_OP_CIPHER_SERVER_PREFERENCE; -+ ssl_op_disable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE; -+ } else { -+ ssl_op_disable |= SSL_OP_CIPHER_SERVER_PREFERENCE; -+ ssl_op_enable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE; -+ } - } else if(!regexec(&Ciphers, lin, 4, matches, 0)) { - has_other = 1; - if(res->ctx == NULL) -@@ -1105,12 +1198,19 @@ - conf_err("ListenHTTPS: can't set SNI callback"); - #endif - for(pc = res->ctx; pc; pc = pc->next) { -+ SSL_CTX_set_app_data(pc->ctx, res); - SSL_CTX_set_mode(pc->ctx, SSL_MODE_AUTO_RETRY); -- SSL_CTX_set_options(pc->ctx, SSL_OP_ALL); -+ SSL_CTX_set_options(pc->ctx, ssl_op_enable); -+ SSL_CTX_clear_options(pc->ctx, ssl_op_disable); -+ if (res->disable_ssl_v2 == 1) -+ { -+ SSL_CTX_set_options(pc->ctx, SSL_OP_NO_SSLv2); -+ } - sprintf(lin, "%d-Pound-%ld", getpid(), random()); - SSL_CTX_set_session_id_context(pc->ctx, (unsigned char *)lin, strlen(lin)); - SSL_CTX_set_tmp_rsa_callback(pc->ctx, RSA_tmp_callback); - SSL_CTX_set_tmp_dh_callback(pc->ctx, DH_tmp_callback); -+ SSL_CTX_set_info_callback(pc->ctx, SSLINFO_callback); - } - return res; - } else { -@@ -1305,6 +1405,9 @@ - || regcomp(&DynScale, "^[ \t]*DynScale[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) - || regcomp(&ClientCert, "^[ \t]*ClientCert[ \t]+([0-3])[ \t]+([1-9])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) - || regcomp(&AddHeader, "^[ \t]*AddHeader[ \t]+"(.+)"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) -+ || regcomp(&SSLAllowClientRenegotiation, "^[ \t]*SSLAllowClientRenegotiation[ \t]+([012])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) -+ || regcomp(&DisableSSLv2, "^[ \t]*DisableSSLv2[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) -+ || regcomp(&SSLHonorCipherOrder, "^[ \t]*SSLHonorCipherOrder[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) - || regcomp(&Ciphers, "^[ \t]*Ciphers[ \t]+"(.+)"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) - || regcomp(&CAlist, "^[ \t]*CAlist[ \t]+"(.+)"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) - || regcomp(&VerifyList, "^[ \t]*VerifyList[ \t]+"(.+)"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED) -@@ -1463,6 +1566,9 @@ - regfree(&DynScale); - regfree(&ClientCert); - regfree(&AddHeader); -+ regfree(&SSLAllowClientRenegotiation); -+ regfree(&DisableSSLv2); -+ regfree(&SSLHonorCipherOrder); - regfree(&Ciphers); - regfree(&CAlist); - regfree(&VerifyList); -diff -Naur Pound-2.6.orig/http.c Pound-2.6.reneg-ciphers-altnames-nosslv2/http.c ---- Pound-2.6.orig/http.c 2011-12-28 14:57:45.000000000 +0100 -+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/http.c 2012-02-15 21:44:46.000000000 +0100 -@@ -246,6 +246,11 @@ - - static int err_to = -1; - -+typedef struct { -+ int timeout; -+ RENEG_STATE *reneg_state; -+} BIO_ARG; -+ - /* - * Time-out for client read/gets - * the SSL manual says not to do it, but it works well enough anyway... -@@ -253,18 +258,32 @@ - static long - bio_callback(BIO *const bio, const int cmd, const char *argp, int argi, long argl, long ret) - { -+ BIO_ARG *bio_arg; - struct pollfd p; - int to, p_res, p_err; - - if(cmd != BIO_CB_READ && cmd != BIO_CB_WRITE) - return ret; - -+ //logmsg(LOG_NOTICE, "bio callback"); - /* a time-out already occured */ -- if((to = *((int *)BIO_get_callback_arg(bio)) * 1000) < 0) { -+ if((bio_arg = (BIO_ARG*)BIO_get_callback_arg(bio))==NULL) return ret; -+ if((to = bio_arg->timeout * 1000) < 0) { - errno = ETIMEDOUT; - return -1; - } - -+ /* Renegotiations */ -+ //logmsg(LOG_NOTICE, "RENEG STATE %d", bio_arg->reneg_state==NULL?-1:*bio_arg->reneg_state); -+ if (bio_arg->reneg_state != NULL && *bio_arg->reneg_state == RENEG_ABORT) { -+ logmsg(LOG_NOTICE, "REJECTING renegotiated session"); -+ errno = ECONNABORTED; -+ return -1; -+ } -+ -+ //logmsg(LOG_NOTICE, "TO %d", to); -+ if (to == 0) return ret; -+ - for(;;) { - memset(&p, 0, sizeof(p)); - BIO_get_fd(bio, &p.fd); -@@ -299,7 +318,7 @@ - return -1; - case 0: - /* timeout - mark the BIO as unusable for the future */ -- BIO_set_callback_arg(bio, (char *)&err_to); -+ bio_arg->timeout = err_to; - #ifdef EBUG - logmsg(LOG_WARNING, "(%lx) CALLBACK timeout poll after %d secs: %s", - pthread_self(), to / 1000, strerror(p_err)); -@@ -503,7 +522,14 @@ - regmatch_t matches[4]; - struct linger l; - double start_req, end_req; -+ RENEG_STATE reneg_state; -+ BIO_ARG ba1, ba2; - -+ reneg_state = RENEG_INIT; -+ ba1.reneg_state = &reneg_state; -+ ba2.reneg_state = &reneg_state; -+ ba1.timeout = 0; -+ ba2.timeout = 0; - from_host = ((thr_arg *)arg)->from_host; - memcpy(&from_host_addr, from_host.ai_addr, from_host.ai_addrlen); - from_host.ai_addr = (struct sockaddr *)&from_host_addr; -@@ -512,6 +538,8 @@ - free(((thr_arg *)arg)->from_host.ai_addr); - free(arg); - -+ if(lstn->allow_client_reneg) reneg_state = RENEG_ALLOW; -+ - n = 1; - setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&n, sizeof(n)); - l.l_onoff = 1; -@@ -535,10 +563,11 @@ - close(sock); - return; - } -- if(lstn->to > 0) { -- BIO_set_callback_arg(cl, (char *)&lstn->to); -+ //if(lstn->to > 0) { -+ ba1.timeout = lstn->to; -+ BIO_set_callback_arg(cl, (char *)&ba1); - BIO_set_callback(cl, bio_callback); -- } -+ //} - - if(lstn->ctx != NULL) { - if((ssl = SSL_new(lstn->ctx->ctx)) == NULL) { -@@ -547,6 +576,7 @@ - BIO_free_all(cl); - return; - } -+ SSL_set_app_data(ssl, &reneg_state); - SSL_set_bio(ssl, cl, cl); - if((bb = BIO_new(BIO_f_ssl())) == NULL) { - logmsg(LOG_WARNING, "(%lx) BIO_new(Bio_f_ssl()) failed", pthread_self()); -@@ -848,7 +878,8 @@ - } - BIO_set_close(be, BIO_CLOSE); - if(backend->to > 0) { -- BIO_set_callback_arg(be, (char *)&backend->to); -+ ba2.timeout = backend->to; -+ BIO_set_callback_arg(be, (char *)&ba2); - BIO_set_callback(be, bio_callback); - } - if(backend->ctx != NULL) { -diff -Naur Pound-2.6.orig/pound.8 Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.8 ---- Pound-2.6.orig/pound.8 2011-12-28 14:57:45.000000000 +0100 -+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.8 2012-02-15 21:44:46.000000000 +0100 -@@ -501,6 +501,19 @@ - and - .I SSL_CTX_set_cipher_list(3). - .TP -+\fBSSLHonorCipherOrder\fR 0|1 -+If this value is 1, the server will broadcast a preference to use \fBCiphers\fR in the -+order supplied in the \fBCiphers\fR directive. If the value is 0, the server will treat -+the Ciphers list as the list of Ciphers it will accept, but no preference will be -+indicated. Default value is 0. -+.TP -+\fBSSLAllowClientRenegotiation\fR 0|1|2 -+If this value is 0, client initiated renegotiation will be disabled. This will mitigate -+DoS exploits based on client renegotiation, regardless of the patch status of clients and -+servers related to "Secure renegotiation". If the value is 1, secure renegotiation is -+supported. If the value is 2, insecure renegotiation is supported, with unpatched -+clients. /fBThis can lead to a DoS and a Man in the Middle attack!/fR Default value is 0. -+.TP - \fBCAlist\fR "CAcert_file" - Set the list of "trusted" CA's for this server. The CAcert_file is a file containing - a sequence of CA certificates (PEM format). The names of the defined CA certificates -diff -Naur Pound-2.6.orig/pound.h Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.h ---- Pound-2.6.orig/pound.h 2011-12-28 14:57:45.000000000 +0100 -+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.h 2012-02-15 21:49:39.000000000 +0100 -@@ -380,6 +380,8 @@ - SSL_CTX *ctx; - char *server_name; - struct _pound_ctx *next; -+ unsigned int subjectAltNameCount; -+ unsigned char **subjectAltNames; - } POUND_CTX; - - /* Listener definition */ -@@ -404,6 +406,8 @@ - int rewr_dest; /* rewrite destination header */ - int disabled; /* true if the listener is disabled */ - int log_level; /* log level for this listener */ -+ int allow_client_reneg; /* Allow Client SSL Renegotiation */ -+ int disable_ssl_v2; /* Disable SSL version 2 */ - SERVICE *services; - struct _listener *next; - } LISTENER; -@@ -419,6 +423,9 @@ - struct _thr_arg *next; - } thr_arg; /* argument to processing threads: socket, origin */ - -+/* Track SSL handshare/renegotiation so we can reject client-renegotiations. */ -+typedef enum { RENEG_INIT=0, RENEG_REJECT, RENEG_ALLOW, RENEG_ABORT } RENEG_STATE; -+ - /* Header types */ - #define HEADER_ILLEGAL -1 - #define HEADER_OTHER 0 -@@ -591,6 +598,11 @@ - extern DH *DH_tmp_callback(SSL *, int, int); - - /* -+ * Renegotiation callback -+ */ -+extern void SSLINFO_callback(const SSL *s, int where, int rc); -+ -+/* - * expiration stuff - */ - #ifndef EXPIRE_TO -diff -Naur Pound-2.6.orig/svc.c Pound-2.6.reneg-ciphers-altnames-nosslv2/svc.c ---- Pound-2.6.orig/svc.c 2011-12-28 14:57:45.000000000 +0100 -+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/svc.c 2012-02-15 21:44:46.000000000 +0100 -@@ -1797,3 +1797,34 @@ - close(ctl); - } - } -+ -+void -+SSLINFO_callback(const SSL *ssl, int where, int rc) -+{ -+ RENEG_STATE *reneg_state; -+ -+ /* Get our thr_arg where we're tracking this connection info */ -+ if ((reneg_state = (RENEG_STATE *)SSL_get_app_data(ssl)) == NULL) return; -+ -+ /* If we're rejecting renegotiations, move to ABORT if Client Hello is being read. */ -+ if ((where & SSL_CB_ACCEPT_LOOP) && *reneg_state == RENEG_REJECT) { -+ int state = SSL_get_state(ssl); -+ -+ if (state == SSL3_ST_SR_CLNT_HELLO_A || state == SSL23_ST_SR_CLNT_HELLO_A) { -+ *reneg_state = RENEG_ABORT; -+ logmsg(LOG_WARNING,"rejecting client initiated renegotiation"); -+ } -+ } -+ else if (where & SSL_CB_HANDSHAKE_DONE && *reneg_state == RENEG_INIT) { -+ // Reject any followup renegotiations -+ *reneg_state = RENEG_REJECT; -+ } -+ -+ //if (where & SSL_CB_HANDSHAKE_START) logmsg(LOG_DEBUG, "handshake start"); -+ //else if (where & SSL_CB_HANDSHAKE_DONE) logmsg(LOG_DEBUG, "handshake done"); -+ //else if (where & SSL_CB_LOOP) logmsg(LOG_DEBUG, "loop"); -+ //else if (where & SSL_CB_READ) logmsg(LOG_DEBUG, "read"); -+ //else if (where & SSL_CB_WRITE) logmsg(LOG_DEBUG, "write"); -+ //else if (where & SSL_CB_ALERT) logmsg(LOG_DEBUG, "alert"); -+} -+ diff --git a/src/patches/compat-drivers-3.8-1-u-kref_get_unless_zero.patch b/src/patches/compat-drivers-3.8-1-u-kref_get_unless_zero.patch deleted file mode 100644 index 1930d80..0000000 --- a/src/patches/compat-drivers-3.8-1-u-kref_get_unless_zero.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- compat-drivers-3.8-1-u/include/linux/compat-3.8.h.orig 2013-05-16 20:35:27.046386772 +0200 -+++ compat-drivers-3.8-1-u/include/linux/compat-3.8.h 2013-05-16 20:35:39.219767618 +0200 -@@ -24,35 +24,6 @@ - - /* This backports: - * -- * commit 4b20db3de8dab005b07c74161cb041db8c5ff3a7 -- * Author: Thomas Hellstrom thellstrom@vmware.com -- * Date: Tue Nov 6 11:31:49 2012 +0000 -- * -- * kref: Implement kref_get_unless_zero v3 -- */ --/** -- * kref_get_unless_zero - Increment refcount for object unless it is zero. -- * @kref: object. -- * -- * Return non-zero if the increment succeeded. Otherwise return 0. -- * -- * This function is intended to simplify locking around refcounting for -- * objects that can be looked up from a lookup structure, and which are -- * removed from that lookup structure in the object destructor. -- * Operations on such objects require at least a read lock around -- * lookup + kref_get, and a write lock around kref_put + remove from lookup -- * structure. Furthermore, RCU implementations become extremely tricky. -- * With a lookup followed by a kref_get_unless_zero *with return value check* -- * locking in the kref_put path can be deferred to the actual removal from -- * the lookup structure and RCU lookups become trivial. -- */ --static inline int __must_check kref_get_unless_zero(struct kref *kref) --{ -- return atomic_add_unless(&kref->refcount, 1, 0); --} -- --/* This backports: -- * - * commit 83e68189745ad931c2afd45d8ee3303929233e7f - * Author: Matt Fleming matt.fleming@intel.com - * Date: Wed Nov 14 09:42:35 2012 +0000 diff --git a/src/patches/compat-wireless-2.6.34-usbnet_compile.patch b/src/patches/compat-wireless-2.6.34-usbnet_compile.patch deleted file mode 100644 index 36146fb..0000000 --- a/src/patches/compat-wireless-2.6.34-usbnet_compile.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff -Naur compat-wireless-2.6.34.org/include/linux/usb/usbnet.h compat-wireless-2.6.34/include/linux/usb/usbnet.h ---- compat-wireless-2.6.34.org/include/linux/usb/usbnet.h 2010-05-18 03:12:10.000000000 +0200 -+++ compat-wireless-2.6.34/include/linux/usb/usbnet.h 2010-05-22 22:18:34.000000000 +0200 -@@ -214,4 +214,24 @@ - extern void usbnet_get_drvinfo (struct net_device *, struct ethtool_drvinfo *); - extern int usbnet_nway_reset(struct net_device *net); - -+/* messaging support includes the interface name, so it must not be -+ * used before it has one ... notably, in minidriver bind() calls. -+ */ -+#ifdef DEBUG -+#define devdbg(usbnet, fmt, arg...) \ -+ printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , ## arg) -+#else -+#define devdbg(usbnet, fmt, arg...) \ -+ ({ if (0) printk(KERN_DEBUG "%s: " fmt "\n" , (usbnet)->net->name , \ -+ ## arg); 0; }) -+#endif -+ -+#define deverr(usbnet, fmt, arg...) \ -+ printk(KERN_ERR "%s: " fmt "\n" , (usbnet)->net->name , ## arg) -+#define devwarn(usbnet, fmt, arg...) \ -+ printk(KERN_WARNING "%s: " fmt "\n" , (usbnet)->net->name , ## arg) -+ -+#define devinfo(usbnet, fmt, arg...) \ -+ printk(KERN_INFO "%s: " fmt "\n" , (usbnet)->net->name , ## arg); \ -+ - #endif /* __LINUX_USB_USBNET_H */ diff --git a/src/patches/compat-wireless-2.6.39_kfifo_module_info.patch b/src/patches/compat-wireless-2.6.39_kfifo_module_info.patch deleted file mode 100644 index eb5d280..0000000 --- a/src/patches/compat-wireless-2.6.39_kfifo_module_info.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -Naur compat-wireless-2.6.39-1-sn.org/compat/kfifo.c compat-wireless-2.6.39-1-sn/compat/kfifo.c ---- compat-wireless-2.6.39-1-sn.org/compat/kfifo.c 2011-05-24 01:43:48.000000000 +0200 -+++ compat-wireless-2.6.39-1-sn/compat/kfifo.c 2011-05-24 17:20:06.956818313 +0200 -@@ -27,6 +27,10 @@ - #include <linux/uaccess.h> - #include <linux/kfifo.h> - -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Stefani Seibold stefani@seibold.net"); -+MODULE_DESCRIPTION("A generic kernel FIFO implementation"); -+ - /* - * internal helper to calculate the unused elements in a fifo - */ diff --git a/src/patches/compat-wireless-3.5-build_ath5k_only_with_pci.patch b/src/patches/compat-wireless-3.5-build_ath5k_only_with_pci.patch deleted file mode 100644 index 2e82157..0000000 --- a/src/patches/compat-wireless-3.5-build_ath5k_only_with_pci.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff -Naur compat-wireless-3.5-1-snpc.org/config.mk compat-wireless-3.5/config.mk ---- compat-wireless-3.5-1-snpc.org/config.mk 2012-07-31 17:22:29.000000000 -0400 -+++ compat-wireless-3.5/config.mk 2012-08-13 13:09:55.913234600 -0400 -@@ -246,10 +246,12 @@ - # mac80211 test driver - export CONFIG_MAC80211_HWSIM=m - -+ifdef CONFIG_PCI - export CONFIG_ATH5K=m - # export CONFIG_ATH5K_DEBUG=y - # export CONFIG_ATH5K_TRACER=y - # export CONFIG_ATH5K_AHB=y -+endif #CONFIG_PCI - - export CONFIG_ATH9K=m - export CONFIG_ATH9K_HW=m diff --git a/src/patches/compat-wireless-3.5-libertas_uap.patch b/src/patches/compat-wireless-3.5-libertas_uap.patch deleted file mode 100644 index 633bb67..0000000 --- a/src/patches/compat-wireless-3.5-libertas_uap.patch +++ /dev/null @@ -1,5080 +0,0 @@ -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/Makefile compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/Makefile ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/Makefile 2012-07-31 14:23:04.000000000 +0200 -@@ -0,0 +1,6 @@ -+obj-$(CONFIG_LIBERTAS_UAP) += uap8xxx.o -+ -+uap8xxx-y += uap_main.o uap_sdio_mmc.o -+uap8xxx-$(CONFIG_PROC_FS) += uap_proc.o uap_debug.o -+ -+EXTRA_CFLAGS += -DFPNUM='"52"' -DPXA3XX_DMA_ALIGN -DDEBUG_LEVEL1 -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_debug.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_debug.c ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_debug.c 1970-01-01 01:00:00.000000000 +0100 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_debug.c 2012-07-31 14:23:04.000000000 +0200 -@@ -0,0 +1,261 @@ -+/** @file uap_debug.c -+ * @brief This file contains functions for debug proc file. -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+#ifdef CONFIG_PROC_FS -+#include "uap_headers.h" -+ -+/******************************************************** -+ Local Variables -+********************************************************/ -+ -+#define item_size(n) (sizeof ((uap_adapter *)0)->n) -+#define item_addr(n) ((u32) &((uap_adapter *)0)->n) -+ -+#define item_dbg_size(n) (sizeof (((uap_adapter *)0)->dbg.n)) -+#define item_dbg_addr(n) ((u32) &(((uap_adapter *)0)->dbg.n)) -+ -+#define item_dev_size(n) (sizeof ((uap_dev_t *)0)->n) -+#define item_dev_addr(n) ((u32) &((uap_dev_t *)0)->n) -+ -+/** MicroAp device offset */ -+#define OFFSET_UAP_DEV 0x01 -+/** Bluetooth adapter offset */ -+#define OFFSET_UAP_ADAPTER 0x02 -+ -+struct debug_data -+{ -+ /** Name */ -+ char name[32]; -+ /** Size */ -+ u32 size; -+ /** Address */ -+ u32 addr; -+ /** Offset */ -+ u32 offset; -+ /** Flag */ -+ u32 flag; -+}; -+ -+/* To debug any member of uap_adapter, simply add one line here. -+ */ -+static struct debug_data items[] = { -+ {"cmd_sent", item_dev_size(cmd_sent), 0, item_dev_addr(cmd_sent), -+ OFFSET_UAP_DEV}, -+ {"data_sent", item_dev_size(data_sent), 0, item_dev_addr(data_sent), -+ OFFSET_UAP_DEV}, -+ {"IntCounter", item_size(IntCounter), 0, item_addr(IntCounter), -+ OFFSET_UAP_ADAPTER}, -+ {"cmd_pending", item_size(cmd_pending), 0, item_addr(cmd_pending), -+ OFFSET_UAP_ADAPTER}, -+ {"num_cmd_h2c_fail", item_dbg_size(num_cmd_host_to_card_failure), 0, -+ item_dbg_addr(num_cmd_host_to_card_failure), OFFSET_UAP_ADAPTER}, -+ {"num_tx_h2c_fail", item_dbg_size(num_tx_host_to_card_failure), 0, -+ item_dbg_addr(num_tx_host_to_card_failure), OFFSET_UAP_ADAPTER}, -+ {"psmode", item_size(psmode), 0, item_addr(psmode), OFFSET_UAP_ADAPTER}, -+ {"ps_state", item_size(ps_state), 0, item_addr(ps_state), -+ OFFSET_UAP_ADAPTER}, -+#ifdef DEBUG_LEVEL1 -+ {"drvdbg", sizeof(drvdbg), (u32) & drvdbg, 0, 0} -+#endif -+}; -+ -+static int num_of_items = sizeof(items) / sizeof(items[0]); -+ -+/******************************************************** -+ Global Variables -+********************************************************/ -+ -+/******************************************************** -+ Local Functions -+********************************************************/ -+/** -+ * @brief proc read function -+ * -+ * @param page pointer to buffer -+ * @param s read data starting position -+ * @param off offset -+ * @param cnt counter -+ * @param eof end of file flag -+ * @param data data to output -+ * @return number of output data -+ */ -+static int -+uap_debug_read(char *page, char **s, off_t off, int cnt, int *eof, void *data) -+{ -+ int val = 0; -+ char *p = page; -+ int i; -+ -+ struct debug_data *d = (struct debug_data *) data; -+ -+ if (MODULE_GET == 0) -+ return UAP_STATUS_FAILURE; -+ -+ for (i = 0; i < num_of_items; i++) { -+ if (d[i].size == 1) -+ val = *((u8 *) d[i].addr); -+ else if (d[i].size == 2) -+ val = *((u16 *) d[i].addr); -+ else if (d[i].size == 4) -+ val = *((u32 *) d[i].addr); -+ -+ p += sprintf(p, "%s=%d\n", d[i].name, val); -+ } -+ MODULE_PUT; -+ return p - page; -+} -+ -+/** -+ * @brief proc write function -+ * -+ * @param f file pointer -+ * @param buf pointer to data buffer -+ * @param cnt data number to write -+ * @param data data to write -+ * @return number of data -+ */ -+static int -+uap_debug_write(struct file *f, const char *buf, unsigned long cnt, void *data) -+{ -+ int r, i; -+ char *pdata; -+ char *p; -+ char *p0; -+ char *p1; -+ char *p2; -+ struct debug_data *d = (struct debug_data *) data; -+ -+ if (MODULE_GET == 0) -+ return UAP_STATUS_FAILURE; -+ -+ pdata = (char *) kmalloc(cnt, GFP_KERNEL); -+ if (pdata == NULL) { -+ MODULE_PUT; -+ return 0; -+ } -+ -+ if (copy_from_user(pdata, buf, cnt)) { -+ PRINTM(INFO, "Copy from user failed\n"); -+ kfree(pdata); -+ MODULE_PUT; -+ return 0; -+ } -+ -+ p0 = pdata; -+ for (i = 0; i < num_of_items; i++) { -+ do { -+ p = strstr(p0, d[i].name); -+ if (p == NULL) -+ break; -+ p1 = strchr(p, '\n'); -+ if (p1 == NULL) -+ break; -+ p0 = p1++; -+ p2 = strchr(p, '='); -+ if (!p2) -+ break; -+ p2++; -+ r = string_to_number(p2); -+ if (d[i].size == 1) -+ *((u8 *) d[i].addr) = (u8) r; -+ else if (d[i].size == 2) -+ *((u16 *) d[i].addr) = (u16) r; -+ else if (d[i].size == 4) -+ *((u32 *) d[i].addr) = (u32) r; -+ break; -+ } while (TRUE); -+ } -+ kfree(pdata); -+#ifdef DEBUG_LEVEL1 -+ printk(KERN_ALERT "drvdbg = 0x%x\n", drvdbg); -+ printk(KERN_ALERT "INFO (%08lx) %s\n", DBG_INFO, -+ (drvdbg & DBG_INFO) ? "X" : ""); -+ printk(KERN_ALERT "WARN (%08lx) %s\n", DBG_WARN, -+ (drvdbg & DBG_WARN) ? "X" : ""); -+ printk(KERN_ALERT "ENTRY (%08lx) %s\n", DBG_ENTRY, -+ (drvdbg & DBG_ENTRY) ? "X" : ""); -+ printk(KERN_ALERT "CMD_D (%08lx) %s\n", DBG_CMD_D, -+ (drvdbg & DBG_CMD_D) ? "X" : ""); -+ printk(KERN_ALERT "DAT_D (%08lx) %s\n", DBG_DAT_D, -+ (drvdbg & DBG_DAT_D) ? "X" : ""); -+ printk(KERN_ALERT "CMND (%08lx) %s\n", DBG_CMND, -+ (drvdbg & DBG_CMND) ? "X" : ""); -+ printk(KERN_ALERT "DATA (%08lx) %s\n", DBG_DATA, -+ (drvdbg & DBG_DATA) ? "X" : ""); -+ printk(KERN_ALERT "ERROR (%08lx) %s\n", DBG_ERROR, -+ (drvdbg & DBG_ERROR) ? "X" : ""); -+ printk(KERN_ALERT "FATAL (%08lx) %s\n", DBG_FATAL, -+ (drvdbg & DBG_FATAL) ? "X" : ""); -+ printk(KERN_ALERT "MSG (%08lx) %s\n", DBG_MSG, -+ (drvdbg & DBG_MSG) ? "X" : ""); -+#endif -+ MODULE_PUT; -+ return cnt; -+} -+ -+/******************************************************** -+ Global Functions -+********************************************************/ -+/** -+ * @brief create debug proc file -+ * -+ * @param priv pointer uap_private -+ * @param dev pointer net_device -+ * @return N/A -+ */ -+void -+uap_debug_entry(uap_private * priv, struct net_device *dev) -+{ -+ int i; -+ struct proc_dir_entry *r; -+ -+ if (priv->proc_entry == NULL) -+ return; -+ -+ for (i = 0; i < num_of_items; i++) { -+ if (items[i].flag & OFFSET_UAP_ADAPTER) -+ items[i].addr = items[i].offset + (u32) priv->adapter; -+ if (items[i].flag & OFFSET_UAP_DEV) -+ items[i].addr = items[i].offset + (u32) & priv->uap_dev; -+ } -+ r = create_proc_entry("debug", 0644, priv->proc_entry); -+ if (r == NULL) -+ return; -+ -+ r->data = &items[0]; -+ r->read_proc = uap_debug_read; -+ r->write_proc = uap_debug_write; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) -+ r->owner = THIS_MODULE; -+#endif -+} -+ -+/** -+ * @brief remove proc file -+ * -+ * @param priv pointer uap_private -+ * @return N/A -+ */ -+void -+uap_debug_remove(uap_private * priv) -+{ -+ remove_proc_entry("debug", priv->proc_entry); -+} -+ -+#endif -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_drv.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_drv.h ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_drv.h 1970-01-01 01:00:00.000000000 +0100 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_drv.h 2012-07-31 14:23:04.000000000 +0200 -@@ -0,0 +1,667 @@ -+/** @file uap_drv.h -+ * @brief This file contains Linux OS related definitions and -+ * declarations, uAP driver -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+ -+#ifndef _UAP_DRV_H -+#define _UAP_DRV_H -+ -+/** Driver release version */ -+#define DRIVER_VERSION "26146" -+ -+/** True */ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+/** False */ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+/** Bit definitions */ -+#ifndef BIT -+#define BIT(x) (1UL << (x)) -+#endif -+ -+/** Dma addresses are 32-bits wide. */ -+#ifndef __ATTRIB_ALIGN__ -+#define __ATTRIB_ALIGN__ __attribute__((aligned(4))) -+#endif -+ -+/** attribute pack */ -+#ifndef __ATTRIB_PACK__ -+#define __ATTRIB_PACK__ __attribute__ ((packed)) -+#endif -+ -+/** Debug Macro definition*/ -+#ifdef DEBUG_LEVEL1 -+ -+extern u32 drvdbg; -+ -+/** Debug message control bit definition for drvdbg */ -+/** Debug message */ -+#define DBG_MSG BIT(0) -+/** Debug fatal message */ -+#define DBG_FATAL BIT(1) -+/** Debug error message */ -+#define DBG_ERROR BIT(2) -+/** Debug data message */ -+#define DBG_DATA BIT(3) -+/** Debug command message */ -+#define DBG_CMND BIT(4) -+ -+/** Debug data */ -+#define DBG_DAT_D BIT(16) -+/** Debug command */ -+#define DBG_CMD_D BIT(17) -+ -+/** Debug entry */ -+#define DBG_ENTRY BIT(28) -+/** Debug warning */ -+#define DBG_WARN BIT(29) -+/** Debug info */ -+#define DBG_INFO BIT(30) -+ -+/** Print info */ -+#define PRINTM_INFO(msg...) {if (drvdbg & DBG_INFO) printk(KERN_DEBUG msg);} -+/** Print warn message */ -+#define PRINTM_WARN(msg...) {if (drvdbg & DBG_WARN) printk(KERN_DEBUG msg);} -+/** Print entry */ -+#define PRINTM_ENTRY(msg...) {if (drvdbg & DBG_ENTRY) printk(KERN_DEBUG msg);} -+/** Print cmd_d */ -+#define PRINTM_CMD_D(msg...) {if (drvdbg & DBG_CMD_D) printk(KERN_DEBUG msg);} -+/** Print data_d */ -+#define PRINTM_DAT_D(msg...) {if (drvdbg & DBG_DAT_D) printk(KERN_DEBUG msg);} -+/** Print command */ -+#define PRINTM_CMND(msg...) {if (drvdbg & DBG_CMND) printk(KERN_DEBUG msg);} -+/** Print data */ -+#define PRINTM_DATA(msg...) {if (drvdbg & DBG_DATA) printk(KERN_DEBUG msg);} -+/** Print error message */ -+#define PRINTM_ERROR(msg...) {if (drvdbg & DBG_ERROR) printk(KERN_DEBUG msg);} -+/** Print fatal message */ -+#define PRINTM_FATAL(msg...) {if (drvdbg & DBG_FATAL) printk(KERN_DEBUG msg);} -+/** Print message */ -+#define PRINTM_MSG(msg...) {if (drvdbg & DBG_MSG) printk(KERN_ALERT msg);} -+/** Print level */ -+#define PRINTM(level,msg...) PRINTM_##level(msg) -+ -+#else -+ -+#define PRINTM(level,msg...) do {} while (0) -+ -+#endif /* DEBUG_LEVEL1 */ -+ -+/** Wait until a condition becomes true */ -+#define ASSERT(cond) \ -+do { \ -+ if (!(cond)) \ -+ PRINTM(INFO, "ASSERT: %s, %s:%i\n", \ -+ __FUNCTION__, __FILE__, __LINE__); \ -+} while(0) -+ -+/** Log enrty point for debugging */ -+#define ENTER() PRINTM(ENTRY, "Enter: %s, %s:%i\n", __FUNCTION__, \ -+ __FILE__, __LINE__) -+/** Log exit point for debugging */ -+#define LEAVE() PRINTM(ENTRY, "Leave: %s, %s:%i\n", __FUNCTION__, \ -+ __FILE__, __LINE__) -+ -+#ifdef DEBUG_LEVEL1 -+/** Dump buffer length */ -+#define DBG_DUMP_BUF_LEN 64 -+/** Maximum dump per line */ -+#define MAX_DUMP_PER_LINE 16 -+/** Data dump length */ -+#define DATA_DUMP_LEN 32 -+ -+static inline void -+hexdump(char *prompt, u8 * buf, int len) -+{ -+ int i; -+ char dbgdumpbuf[DBG_DUMP_BUF_LEN]; -+ char *ptr = dbgdumpbuf; -+ -+ printk(KERN_DEBUG "%s:\n", prompt); -+ for (i = 1; i <= len; i++) { -+ ptr += sprintf(ptr, "%02x ", *buf); -+ buf++; -+ if (i % MAX_DUMP_PER_LINE == 0) { -+ *ptr = 0; -+ printk(KERN_DEBUG "%s\n", dbgdumpbuf); -+ ptr = dbgdumpbuf; -+ } -+ } -+ if (len % MAX_DUMP_PER_LINE) { -+ *ptr = 0; -+ printk(KERN_DEBUG "%s\n", dbgdumpbuf); -+ } -+} -+ -+/** Debug command */ -+#define DBG_HEXDUMP_CMD_D(x,y,z) {if (drvdbg & DBG_CMD_D) hexdump(x,y,z);} -+/** Debug data */ -+#define DBG_HEXDUMP_DAT_D(x,y,z) {if (drvdbg & DBG_DAT_D) hexdump(x,y,z);} -+/** Debug hexdump */ -+#define DBG_HEXDUMP(level,x,y,z) DBG_HEXDUMP_##level(x,y,z) -+/** hexdump */ -+#define HEXDUMP(x,y,z) {if (drvdbg & DBG_INFO) hexdump(x,y,z);} -+#else -+/** Do nothing since debugging is not turned on */ -+#define DBG_HEXDUMP(level,x,y,z) do {} while (0) -+/** Do nothing since debugging is not turned on */ -+#define HEXDUMP(x,y,z) do {} while (0) -+#endif -+ -+/** -+ * Typedefs -+ */ -+/** Unsigned char */ -+typedef u8 BOOLEAN; -+ -+/* -+ * OS macro definitions -+ */ -+/** OS macro to get time */ -+#define os_time_get() jiffies -+ -+/** OS macro to update transfer start time */ -+#define UpdateTransStart(dev) { \ -+ dev->trans_start = jiffies; \ -+} -+ -+/** Try to get a reference to the module */ -+#define MODULE_GET try_module_get(THIS_MODULE) -+/** Decrease module reference count */ -+#define MODULE_PUT module_put(THIS_MODULE) -+ -+/** OS macro to initialize semaphore */ -+#define OS_INIT_SEMAPHORE(x) sema_init(x,1) -+/** OS macro to acquire blocking semaphore */ -+#define OS_ACQ_SEMAPHORE_BLOCK(x) down_interruptible(x) -+/** OS macro to acquire non-blocking semaphore */ -+#define OS_ACQ_SEMAPHORE_NOBLOCK(x) down_trylock(x) -+/** OS macro to release semaphore */ -+#define OS_REL_SEMAPHORE(x) up(x) -+ -+static inline void -+os_sched_timeout(u32 millisec) -+{ -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout((millisec * HZ) / 1000); -+} -+ -+/** Maximum size of ethernet packet */ -+#define MRVDRV_MAXIMUM_ETH_PACKET_SIZE 1514 -+ -+/** Maximum size of multicast list */ -+#define MRVDRV_MAX_MULTICAST_LIST_SIZE 32 -+ -+/** Find minimum */ -+#ifndef MIN -+#define MIN(a,b) ((a) < (b) ? (a) : (b)) -+#endif -+ -+/** Find maximum */ -+#ifndef MAX -+#define MAX(a,b) ((a) > (b) ? (a) : (b)) -+#endif -+ -+/** Find number of elements */ -+#ifndef NELEMENTS -+#define NELEMENTS(x) (sizeof(x)/sizeof(x[0])) -+#endif -+ -+/** Buffer Constants */ -+ -+/** Size of command buffer */ -+#define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024) -+ -+/** Length of device length */ -+#define DEV_NAME_LEN 32 -+ -+/** Length of ethernet address */ -+#ifndef ETH_ALEN -+#define ETH_ALEN 6 -+#endif -+ -+/** Default watchdog timeout */ -+#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (2 * HZ) -+ -+/** Success */ -+#define UAP_STATUS_SUCCESS (0) -+/** Failure */ -+#define UAP_STATUS_FAILURE (-1) -+/** Not accepted */ -+#define UAP_STATUS_NOT_ACCEPTED (-2) -+ -+/** Max loop count (* 100ms) for waiting device ready at init time */ -+#define MAX_WAIT_DEVICE_READY_COUNT 50 -+ -+/** Tx high watermark. Stop Tx queue after this is crossed */ -+#define TX_HIGH_WATERMARK 4 -+/** Tx low watermark. Restart Tx queue after this is crossed */ -+#define TX_LOW_WATERMARK 2 -+ -+/** Netlink protocol number */ -+#define NETLINK_MARVELL (MAX_LINKS - 1) -+/** Netlink maximum payload size */ -+#define NL_MAX_PAYLOAD 1024 -+/** Netlink multicast group number */ -+#define NL_MULTICAST_GROUP 1 -+ -+/** 20 seconds */ -+#define MRVDRV_TIMER_20S 20000 -+ -+/** Host Command option for wait till Send */ -+#define HostCmd_OPTION_WAITFORSEND 0x0001 -+/** Host Command option for wait for RSP */ -+#define HostCmd_OPTION_WAITFORRSP 0x0002 -+/** Host Command option for wait for RSP or Timeout */ -+#define HostCmd_OPTION_WAITFORRSP_TIMEOUT 0x0003 -+/** Host Command option for wait for RSP of sleep confirm */ -+#define HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM 0x0004 -+ -+/** Sleep until a condition gets true or a timeout elapses */ -+#define os_wait_interruptible_timeout(waitq, cond, timeout) \ -+ wait_event_interruptible_timeout(waitq, cond, ((timeout) * HZ / 1000)) -+ -+/** Private command ID to Host command */ -+#define UAPHOSTCMD (SIOCDEVPRIVATE + 1) -+ -+/** Private command ID to Power Mode */ -+#define UAP_POWER_MODE (SIOCDEVPRIVATE + 3) -+/** sleep_param */ -+typedef struct _ps_sleep_param -+{ -+ /** control bitmap */ -+ u32 ctrl_bitmap; -+ /** minimum sleep period (micro second) */ -+ u32 min_sleep; -+ /** maximum sleep period (micro second) */ -+ u32 max_sleep; -+} ps_sleep_param; -+ -+/** inactivity sleep_param */ -+typedef struct _inact_sleep_param -+{ -+ /** inactivity timeout (micro second) */ -+ u32 inactivity_to; -+ /** miniumu awake period (micro second) */ -+ u32 min_awake; -+ /** maximum awake period (micro second) */ -+ u32 max_awake; -+} inact_sleep_param; -+ -+/** flag for ps mode */ -+#define PS_FLAG_PS_MODE 1 -+/** flag for sleep param */ -+#define PS_FLAG_SLEEP_PARAM 2 -+/** flag for inactivity sleep param */ -+#define PS_FLAG_INACT_SLEEP_PARAM 4 -+ -+/** Disable power mode */ -+#define PS_MODE_DISABLE 0 -+/** Enable periodic dtim ps */ -+#define PS_MODE_PERIODIC_DTIM 1 -+/** Enable inactivity ps */ -+#define PS_MODE_INACTIVITY 2 -+ -+/** sleep parameter */ -+#define SLEEP_PARAMETER 1 -+/** inactivity sleep parameter */ -+#define INACTIVITY_SLEEP_PARAMETER 2 -+/** ps_mgmt */ -+typedef struct _ps_mgmt -+{ -+ /** flags for valid field */ -+ u16 flags; -+ /** power mode */ -+ u16 ps_mode; -+ /** sleep param */ -+ ps_sleep_param sleep_param; -+ /** inactivity sleep param */ -+ inact_sleep_param inact_param; -+} ps_mgmt; -+ -+/** Semaphore structure */ -+typedef struct semaphore SEMAPHORE; -+ -+/** Global Varibale Declaration */ -+/** Private data structure of the device */ -+typedef struct _uap_private uap_private; -+/** Adapter data structure of the device */ -+typedef struct _uap_adapter uap_adapter; -+/** private structure */ -+extern uap_private *uappriv; -+ -+/** ENUM definition*/ -+ -+/** Hardware status codes */ -+typedef enum _HARDWARE_STATUS -+{ -+ HWReady, -+ HWInitializing, -+ HWReset, -+ HWClosing, -+ HWNotReady -+} HARDWARE_STATUS; -+ -+/** info for debug purpose */ -+typedef struct _uap_dbg -+{ -+ /** Number of host to card command failures */ -+ u32 num_cmd_host_to_card_failure; -+ /** Number of host to card Tx failures */ -+ u32 num_tx_host_to_card_failure; -+} uap_dbg; -+ -+/** Set thread state */ -+#define OS_SET_THREAD_STATE(x) set_current_state(x) -+ -+typedef struct -+{ -+ /** Task */ -+ struct task_struct *task; -+ /** Queue */ -+ wait_queue_head_t waitQ; -+ /** PID */ -+ pid_t pid; -+ /** Private structure */ -+ void *priv; -+} uap_thread; -+ -+static inline void -+uap_activate_thread(uap_thread * thr) -+{ -+ /** Record the thread pid */ -+ thr->pid = current->pid; -+ -+ /** Initialize the wait queue */ -+ init_waitqueue_head(&thr->waitQ); -+} -+ -+static inline void -+uap_deactivate_thread(uap_thread * thr) -+{ -+ thr->pid = 0; -+ return; -+} -+ -+static inline void -+uap_create_thread(int (*uapfunc) (void *), uap_thread * thr, char *name) -+{ -+ thr->task = kthread_run(uapfunc, thr, "%s", name); -+} -+ -+static inline int -+uap_terminate_thread(uap_thread * thr) -+{ -+ /* Check if the thread is active or not */ -+ if (!thr->pid) -+ return -1; -+ kthread_stop(thr->task); -+ return 0; -+} -+ -+/** Data structure for the Marvell uAP device */ -+typedef struct _uap_dev -+{ -+ /** device name */ -+ char name[DEV_NAME_LEN]; -+ /** card pointer */ -+ void *card; -+ /** IO port */ -+ u32 ioport; -+ /** Rx unit */ -+ u8 rx_unit; -+ /** Data sent: -+ TRUE - Data is sent to fw, no Tx Done received -+ FALSE - Tx done received for previous Tx */ -+ BOOLEAN data_sent; -+ /** CMD sent: -+ TRUE - CMD is sent to fw, no CMD Done received -+ FALSE - CMD done received for previous CMD */ -+ BOOLEAN cmd_sent; -+ /** netdev pointer */ -+ struct net_device *netdev; -+} uap_dev_t, *puap_dev_t; -+ -+/** Private structure for the MV device */ -+struct _uap_private -+{ -+ /** Device open */ -+ int open; -+ -+ /** Device adapter structure */ -+ uap_adapter *adapter; -+ /** Device structure */ -+ uap_dev_t uap_dev; -+ -+ /** Net device statistics structure */ -+ struct net_device_stats stats; -+ -+ /** Number of Tx timeouts */ -+ u32 num_tx_timeout; -+ -+ /** Media connection status */ -+ BOOLEAN MediaConnected; -+ -+#ifdef CONFIG_PROC_FS -+ struct proc_dir_entry *proc_uap; -+ struct proc_dir_entry *proc_entry; -+#endif /* CONFIG_PROC_FS */ -+ -+ /** Firmware helper */ -+ const struct firmware *fw_helper; -+ /** Firmware */ -+ const struct firmware *firmware; -+ /** Hotplug device */ -+ struct device *hotplug_device; -+ /** thread to service interrupts */ -+ uap_thread MainThread; -+ /** Driver lock */ -+ spinlock_t driver_lock; -+ /** Driver lock flags */ -+ ulong driver_flags; -+ -+}; -+ -+/** PS_CMD_ConfirmSleep */ -+typedef struct _PS_CMD_ConfirmSleep -+{ -+ /** SDIO Length */ -+ u16 SDLen; -+ /** SDIO Type */ -+ u16 SDType; -+ /** Command */ -+ u16 Command; -+ /** Size */ -+ u16 Size; -+ /** Sequence number */ -+ u16 SeqNum; -+ /** Result */ -+ u16 Result; -+} __ATTRIB_PACK__ PS_CMD_ConfirmSleep, *PPS_CMD_ConfirmSleep; -+ -+/** Wlan Adapter data structure*/ -+struct _uap_adapter -+{ -+ /** Power save confirm sleep command */ -+ PS_CMD_ConfirmSleep PSConfirmSleep; -+ /** Device status */ -+ HARDWARE_STATUS HardwareStatus; -+ /** Interrupt counter */ -+ u32 IntCounter; -+ /** Tx packet queue */ -+ struct sk_buff_head tx_queue; -+ /** Cmd packet queue */ -+ struct sk_buff_head cmd_queue; -+ /** Command sequence number */ -+ u16 SeqNum; -+ /** Command buffer */ -+ u8 *CmdBuf; -+ /** cmd pending flag */ -+ u8 cmd_pending; -+ /** cmd wait option */ -+ u8 cmd_wait_option; -+ /** Command buffer length */ -+ u32 CmdSize; -+ /** Command wait queue */ -+ wait_queue_head_t cmdwait_q __ATTRIB_ALIGN__; -+ /** Command wait queue state flag */ -+ u8 CmdWaitQWoken; -+ /** PnP support */ -+ BOOLEAN SurpriseRemoved; -+ /** Debug */ -+ uap_dbg dbg; -+ /** Netlink kernel socket */ -+ struct sock *nl_sk; -+ /** Semaphore for CMD */ -+ SEMAPHORE CmdSem; -+ /** Power Save mode */ -+ u8 psmode; -+ /** Power Save state */ -+ u8 ps_state; -+ /** Number of wakeup tries */ -+ u32 WakeupTries; -+}; -+ -+static inline int -+os_upload_rx_packet(uap_private * priv, struct sk_buff *skb) -+{ -+ skb->dev = priv->uap_dev.netdev; -+ skb->protocol = eth_type_trans(skb, priv->uap_dev.netdev); -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ if (in_interrupt()) -+ netif_rx(skb); -+ else -+ netif_rx_ni(skb); -+ return 0; -+} -+ -+/* -+ * netif carrier_on/off and start(wake)/stop_queue handling -+ */ -+static inline void -+os_carrier_on(uap_private * priv) -+{ -+ if (!netif_carrier_ok(priv->uap_dev.netdev) && -+ (priv->MediaConnected == TRUE)) { -+ netif_carrier_on(priv->uap_dev.netdev); -+ } -+} -+ -+static inline void -+os_carrier_off(uap_private * priv) -+{ -+ if (netif_carrier_ok(priv->uap_dev.netdev)) { -+ netif_carrier_off(priv->uap_dev.netdev); -+ } -+} -+ -+static inline void -+os_start_queue(uap_private * priv) -+{ -+ if (netif_queue_stopped(priv->uap_dev.netdev) && -+ (priv->MediaConnected == TRUE)) { -+ netif_wake_queue(priv->uap_dev.netdev); -+ } -+} -+ -+static inline void -+os_stop_queue(uap_private * priv) -+{ -+ if (!netif_queue_stopped(priv->uap_dev.netdev)) { -+ netif_stop_queue(priv->uap_dev.netdev); -+ } -+} -+ -+/** Interface specific header */ -+#define INTF_HEADER_LEN 4 -+ -+/** headroom alignment for tx packet */ -+#define HEADER_ALIGNMENT 8 -+ -+/** The number of times to try when polling for status bits */ -+#define MAX_POLL_TRIES 100 -+ -+/** Length of SNAP header */ -+#define MRVDRV_SNAP_HEADER_LEN 8 -+ -+/** Extra length of Tx packet buffer */ -+#define EXTRA_LEN 36 -+ -+/** Buffer size for ethernet Tx packets */ -+#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \ -+ (ETH_FRAME_LEN + sizeof(TxPD) + EXTRA_LEN) -+ -+/** Buffer size for ethernet Rx packets */ -+#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \ -+ (ETH_FRAME_LEN + sizeof(RxPD) \ -+ + MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN) -+ -+/** Packet type: data, command & event */ -+typedef enum _mv_type -+{ -+ MV_TYPE_DAT = 0, -+ MV_TYPE_CMD = 1, -+ MV_TYPE_EVENT = 3 -+} mv_type; -+ -+/** Disable interrupt */ -+#define OS_INT_DISABLE spin_lock_irqsave(&priv->driver_lock, priv->driver_flags) -+/** Enable interrupt */ -+#define OS_INT_RESTORE spin_unlock_irqrestore(&priv->driver_lock, priv->driver_flags) -+ -+int uap_process_rx_packet(uap_private * priv, struct sk_buff *skb); -+void uap_interrupt(uap_private * priv); -+uap_private *uap_add_card(void *card); -+int uap_remove_card(void *card); -+int uap_process_event(uap_private * priv, u8 * payload, uint len); -+int uap_soft_reset(uap_private * priv); -+int uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len); -+ -+#ifdef CONFIG_PROC_FS -+/** The proc fs interface */ -+void uap_proc_entry(uap_private * priv, struct net_device *dev); -+void uap_proc_remove(uap_private * priv); -+int string_to_number(char *s); -+void uap_debug_entry(uap_private * priv, struct net_device *dev); -+void uap_debug_remove(uap_private * priv); -+#endif /* CONFIG_PROC_FS */ -+ -+int sbi_register(void); -+ -+void sbi_unregister(void); -+int sbi_register_dev(uap_private * priv); -+int sbi_unregister_dev(uap_private * priv); -+int sbi_prog_fw_w_helper(uap_private *); -+ -+int sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb); -+int sbi_enable_host_int(uap_private * priv); -+int sbi_disable_host_int(uap_private * priv); -+ -+int sbi_get_int_status(uap_private * priv, u8 * ireg); -+/** Check firmware status */ -+int sbi_check_fw_status(uap_private *, int); -+int sbi_prog_helper(uap_private *); -+ -+int sbi_wakeup_firmware(uap_private * priv); -+ -+#endif /* _UAP_DRV_H */ -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_fw.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_fw.h ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_fw.h 1970-01-01 01:00:00.000000000 +0100 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_fw.h 2012-07-31 14:23:04.000000000 +0200 -@@ -0,0 +1,359 @@ -+/** @file uap_fw.h -+ * -+ * @brief This file contains firmware specific defines. -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+/******************************************************** -+Change log: -+ 02/26/08: Initial creation -+********************************************************/ -+ -+#ifndef _UAP_FW_H -+#define _UAP_FW_H -+ -+/** uap upload size */ -+#define UAP_UPLD_SIZE 2312 -+/** Packet type Micro AP */ -+#define PKT_TYPE_MICROAP 1 -+/** Packet type client */ -+#define PKT_TYPE_CLIENT 0 -+ -+/** TxPD descriptor */ -+typedef struct _TxPD -+{ -+ /** Bss Type */ -+ u8 BssType; -+ /** Bss num */ -+ u8 BssNum; -+ /** Tx packet length */ -+ u16 TxPktLength; -+ /** Tx packet offset */ -+ u16 TxPktOffset; -+ /** Tx packet type */ -+ u16 TxPktType; -+ /** Tx Control */ -+ u32 TxControl; -+ /** reserved */ -+ u32 reserved[2]; -+} __ATTRIB_PACK__ TxPD, *PTxPD; -+ -+/** RxPD Descriptor */ -+typedef struct _RxPD -+{ -+ /** Bss Type */ -+ u8 BssType; -+ /** Bss Num */ -+ u8 BssNum; -+ /** Tx packet length */ -+ u16 RxPktLength; -+ /** Tx packet offset */ -+ u16 RxPktOffset; -+} __ATTRIB_PACK__ RxPD, *PRxPD; -+ -+#ifdef BIG_ENDIAN -+/** Convert from 16 bit little endian format to CPU format */ -+#define uap_le16_to_cpu(x) le16_to_cpu(x) -+/** Convert from 32 bit little endian format to CPU format */ -+#define uap_le32_to_cpu(x) le32_to_cpu(x) -+/** Convert from 64 bit little endian format to CPU format */ -+#define uap_le64_to_cpu(x) le64_to_cpu(x) -+/** Convert to 16 bit little endian format from CPU format */ -+#define uap_cpu_to_le16(x) cpu_to_le16(x) -+/** Convert to 32 bit little endian format from CPU format */ -+#define uap_cpu_to_le32(x) cpu_to_le32(x) -+/** Convert to 64 bit little endian format from CPU format */ -+#define uap_cpu_to_le64(x) cpu_to_le64(x) -+ -+/** Convert TxPD to little endian format from CPU format */ -+#define endian_convert_TxPD(x); \ -+ { \ -+ (x)->TxPktLength = uap_cpu_to_le16((x)->TxPktLength); \ -+ (x)->TxPktOffset = uap_cpu_to_le32((x)->TxPktOffset); \ -+ (x)->TxControl = uap_cpu_to_le32((x)->TxControl); \ -+ (x)->TxPktType = uap_cpu_to_le32((x)->TxPktType); \ -+ } -+ -+/** Convert RxPD from little endian format to CPU format */ -+#define endian_convert_RxPD(x); \ -+ { \ -+ (x)->RxPktLength = uap_le16_to_cpu((x)->RxPktLength); \ -+ (x)->RxPktOffset = uap_le32_to_cpu((x)->RxPktOffset); \ -+ } -+#else /* BIG_ENDIAN */ -+/** Do nothing */ -+#define uap_le16_to_cpu(x) x -+/** Do nothing */ -+#define uap_le32_to_cpu(x) x -+/** Do nothing */ -+#define uap_le64_to_cpu(x) x -+/** Do nothing */ -+#define uap_cpu_to_le16(x) x -+/** Do nothing */ -+#define uap_cpu_to_le32(x) x -+/** Do nothing */ -+#define uap_cpu_to_le64(x) x -+ -+/** Do nothing */ -+#define endian_convert_TxPD(x) -+/** Do nothing */ -+#define endian_convert_RxPD(x) -+#endif /* BIG_ENDIAN */ -+ -+/** Host Command ID : Function initialization */ -+#define HostCmd_CMD_FUNC_INIT 0x00a9 -+/** Host Command ID : Function shutdown */ -+#define HostCmd_CMD_FUNC_SHUTDOWN 0x00aa -+ -+/** Host Command id: SYS_INFO */ -+#define HOST_CMD_APCMD_SYS_INFO 0x00ae -+/** Host Command id: SYS_RESET */ -+#define HOST_CMD_APCMD_SYS_RESET 0x00af -+/** Host Command id: SYS_CONFIGURE */ -+#define HOST_CMD_APCMD_SYS_CONFIGURE 0x00b0 -+/** Host Command id: BSS_START */ -+#define HOST_CMD_APCMD_BSS_START 0x00b1 -+/** Host Command id: SYS_STOP */ -+#define HOST_CMD_APCMD_BSS_STOP 0x00b2 -+/** Host Command id: STA_LIST */ -+#define HOST_CMD_APCMD_STA_LIST 0x00b3 -+/** Host Command id: STA_FILTER_TABLE */ -+#define HOST_CMD_APCMD_STA_FILTER_TABLE 0x00b4 -+/** Host Command id: STA_DEAUTH */ -+#define HOST_CMD_APCMD_STA_DEAUTH 0x00b5 -+/** Host Command id: SOFT_RESET */ -+#define HOST_CMD_APCMD_SOFT_RESET 0x00d5 -+/** Host Command id: POWER_MGMT_EXT */ -+#define HOST_CMD_POWER_MGMT_EXT 0x00ef -+/** Host Command id: SLEEP_CONFIRM*/ -+#define HOST_CMD_SLEEP_CONFIRM 0x00d8 -+ -+/** TLV type : SSID */ -+#define TLV_TYPE_SSID 0x0000 -+/** TLV type : Rates */ -+#define TLV_TYPE_RATES 0x0001 -+/** TLV type : PHY DS */ -+#define TLV_TYPE_PHY_DS 0x0003 -+ -+/** TLV Id : Base id */ -+#define PROPRIETARY_TLV_BASE_ID 0x0100 -+/** TLV Id : AP_MAC_ADDRESS */ -+#define MRVL_AP_MAC_ADDRESS_TLV_ID (PROPRIETARY_TLV_BASE_ID + 43) -+/** TLV Id : Beacon period */ -+#define MRVL_BEACON_PERIOD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 44) -+/** TLV Id : Dtim period */ -+#define MRVL_DTIM_PERIOD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 45) -+/** TLV Id : Basic rates */ -+#define MRVL_BASIC_RATES_TLV_ID (PROPRIETARY_TLV_BASE_ID + 46) -+/** TLV Id : Tx Power */ -+#define MRVL_TX_POWER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 47) -+/** TLV Id : Broadcast SSID control */ -+#define MRVL_BCAST_SSID_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 48) -+/** TLV Id : Preamble control */ -+#define MRVL_PREAMBLE_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 49) -+/** TLV Id : Antenna control */ -+#define MRVL_ANTENNA_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 50) -+/** TLV Id : RTS threshold */ -+#define MRVL_RTS_THRESHOLD_TLV_ID (PROPRIETARY_TLV_BASE_ID + 51) -+/** TLV Id : Radio control */ -+#define MRVL_RADIO_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 52) -+/** TLV Id : TX data rate */ -+#define MRVL_TX_DATA_RATE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 53) -+/** TLV Id : Packet forward control */ -+#define MRVL_PKT_FWD_CTL_TLV_ID (PROPRIETARY_TLV_BASE_ID + 54) -+/** TLV Id : STA info */ -+#define MRVL_STA_INFO_TLV_ID (PROPRIETARY_TLV_BASE_ID + 55) -+/** TLV Id : STA MAC address filter */ -+#define MRVL_STA_MAC_ADDR_FILTER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 56) -+/** TLV Id : STA ageout timer */ -+#define MRVL_STA_AGEOUT_TIMER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 57) -+/** TLV Id : Security config */ -+#define MRVL_SECURITY_CFG_TLV_ID (PROPRIETARY_TLV_BASE_ID + 58) -+/** TLV Id : WEP KEY */ -+#define MRVL_WEP_KEY_TLV_ID (PROPRIETARY_TLV_BASE_ID + 59) -+/** TLV Id : WPA Passphrase */ -+#define MRVL_WPA_PASSPHRASE_TLV_ID (PROPRIETARY_TLV_BASE_ID + 60) -+ -+/** Action get */ -+#define ACTION_GET 0 -+/** Action set */ -+#define ACTION_SET 1 -+/** Length of ethernet address */ -+#ifndef ETH_ALEN -+#define ETH_ALEN 6 -+#endif -+ -+/** HostCmd_DS_GEN */ -+typedef struct -+{ -+ /** Command */ -+ u16 Command; -+ /** Size */ -+ u16 Size; -+ /** Sequence number */ -+ u16 SeqNum; -+ /** Result */ -+ u16 Result; -+} __ATTRIB_PACK__ HostCmd_DS_GEN; -+ -+/** Size of HostCmd_DS_GEN */ -+#define S_DS_GEN sizeof(HostCmd_DS_GEN) -+ -+/** _HostCmd_HEADER*/ -+typedef struct -+{ -+ /** Command Header : Command */ -+ u16 Command; -+ /** Command Header : Size */ -+ u16 Size; -+} __ATTRIB_PACK__ HostCmd_HEADER; -+ -+/** HostCmd_SYS_CONFIG */ -+typedef struct _HostCmd_SYS_CONFIG -+{ -+ /** CMD Action GET/SET*/ -+ u16 Action; -+ /** Tlv buffer */ -+ u8 TlvBuffer[0]; -+} __ATTRIB_PACK__ HostCmd_SYS_CONFIG; -+ -+/** HostCmd_DS_POWER_MGMT_EXT */ -+typedef struct _HostCmd_DS_POWER_MGMT_EXT -+{ -+ /** CMD Action Get/Set*/ -+ u16 action; -+ /** power mode */ -+ u16 power_mode; -+} __ATTRIB_PACK__ HostCmd_DS_POWER_MGMT_EXT; -+ -+/** _HostCmd_DS_COMMAND*/ -+typedef struct _HostCmd_DS_COMMAND -+{ -+ -+ /** Command Header : Command */ -+ u16 Command; -+ /** Command Header : Size */ -+ u16 Size; -+ /** Command Header : Sequence number */ -+ u16 SeqNum; -+ /** Command Header : Result */ -+ u16 Result; -+ /** Command Body */ -+ union -+ { -+ HostCmd_SYS_CONFIG sys_config; -+ HostCmd_DS_POWER_MGMT_EXT pm_cfg; -+ -+ } params; -+} __ATTRIB_PACK__ HostCmd_DS_COMMAND; -+ -+/** MrvlIEtypesHeader_*/ -+typedef struct _MrvlIEtypesHeader -+{ -+ /** Header type */ -+ u16 Type; -+ /** Header length */ -+ u16 Len; -+} __ATTRIB_PACK__ MrvlIEtypesHeader_t; -+ -+/** MrvlIEtypes_Data_t */ -+typedef struct _MrvlIEtypes_Data_t -+{ -+ /** Header */ -+ MrvlIEtypesHeader_t Header; -+ /** Data */ -+ u8 Data[1]; -+} __ATTRIB_PACK__ MrvlIEtypes_Data_t; -+ -+/** MrvlIEtypes_ChanListParamSet_t */ -+typedef struct _MrvlIEtypes_MacAddr_t -+{ -+ /** Header */ -+ MrvlIEtypesHeader_t Header; -+ /** AP MAC address */ -+ u8 ApMacAddr[ETH_ALEN]; -+} __ATTRIB_PACK__ MrvlIEtypes_MacAddr_t; -+ -+/** Event ID: BSS started */ -+#define MICRO_AP_EV_ID_BSS_START 46 -+ -+/** Event ID: BSS idle event */ -+#define MICRO_AP_EV_BSS_IDLE 67 -+ -+/** Event ID: BSS active event */ -+#define MICRO_AP_EV_BSS_ACTIVE 68 -+ -+/** Event ID: PS_AWAKE */ -+#define EVENT_PS_AWAKE 0x0a -+ -+/** Event ID: PS_SLEEP */ -+#define EVENT_PS_SLEEP 0x0b -+ -+/** PS_STATE */ -+typedef enum _PS_STATE -+{ -+ PS_STATE_AWAKE, -+ PS_STATE_PRE_SLEEP, -+ PS_STATE_SLEEP -+} PS_STATE; -+ -+/** TLV type: AP Sleep param */ -+#define TLV_TYPE_AP_SLEEP_PARAM (PROPRIETARY_TLV_BASE_ID + 106) -+/** TLV type: AP Inactivity Sleep param */ -+#define TLV_TYPE_AP_INACT_SLEEP_PARAM (PROPRIETARY_TLV_BASE_ID + 107) -+ -+/** MrvlIEtypes_sleep_param_t */ -+typedef struct _MrvlIEtypes_sleep_param_t -+{ -+ /** Header */ -+ MrvlIEtypesHeader_t header; -+ /** control bitmap */ -+ u32 ctrl_bitmap; -+ /** min_sleep */ -+ u32 min_sleep; -+ /** max_sleep */ -+ u32 max_sleep; -+} __ATTRIB_PACK__ MrvlIEtypes_sleep_param_t; -+ -+/** MrvlIEtypes_inact_sleep_param_t */ -+typedef struct _MrvlIEtypes_inact_sleep_param_t -+{ -+ /** Header */ -+ MrvlIEtypesHeader_t header; -+ /** inactivity timeout */ -+ u32 inactivity_to; -+ /** min_awake */ -+ u32 min_awake; -+ /** max_awake */ -+ u32 max_awake; -+} __ATTRIB_PACK__ MrvlIEtypes_inact_sleep_param_t; -+ -+/** AP_Event */ -+typedef struct _AP_Event -+{ -+ /** Event ID */ -+ u32 EventId; -+ /* -+ * Reserved for STA_ASSOCIATED event and contains -+ * status information for the MIC_COUNTERMEASURES event. -+ */ -+ /** Reserved/status */ -+ u16 status; -+ /** AP MAC address */ -+ u8 MacAddr[ETH_ALEN]; -+} __ATTRIB_PACK__ AP_Event; -+#endif /* _UAP_FW_H */ -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_headers.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_headers.h ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_headers.h 1970-01-01 01:00:00.000000000 +0100 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_headers.h 2012-07-31 14:23:04.000000000 +0200 -@@ -0,0 +1,64 @@ -+/** @file uap_headers.h -+ * -+ * @brief This file contains all the necessary include file. -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+#ifndef _UAP_HEADERS_H -+#define _UAP_HEADERS_H -+ -+/* Linux header files */ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/version.h> -+#include <linux/param.h> -+#include <linux/types.h> -+#include <linux/interrupt.h> -+#include <linux/proc_fs.h> -+#include <linux/kthread.h> -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) -+#include <linux/semaphore.h> -+#else -+#include <asm/semaphore.h> -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) -+#include <linux/config.h> -+#endif -+ -+/* Net header files */ -+#include <linux/netdevice.h> -+#include <linux/net.h> -+#include <linux/skbuff.h> -+#include <linux/if_ether.h> -+#include <linux/etherdevice.h> -+#include <net/sock.h> -+#include <linux/netlink.h> -+#include <linux/firmware.h> -+#include <linux/delay.h> -+ -+#include "uap_drv.h" -+#include "uap_fw.h" -+ -+#include <linux/mmc/sdio.h> -+#include <linux/mmc/sdio_ids.h> -+#include <linux/mmc/sdio_func.h> -+#include <linux/mmc/card.h> -+#include "uap_sdio_mmc.h" -+ -+#endif /* _UAP_HEADERS_H */ -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_main.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_main.c ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_main.c 1970-01-01 01:00:00.000000000 +0100 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_main.c 2012-07-31 14:25:28.473230753 +0200 -@@ -0,0 +1,1815 @@ -+/** @file uap_main.c -+ * @brief This file contains the major functions in uAP -+ * driver. It includes init, exit etc.. -+ * This file also contains the initialization for SW, -+ * FW and HW -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+/** -+ * @mainpage uAP Linux Driver -+ * -+ * @section overview_sec Overview -+ * -+ * This is Linux reference driver for Marvell uAP. -+ * -+ * @section copyright_sec Copyright -+ * -+ * Copyright (C) 2008, Marvell International Ltd. -+ * -+ */ -+ -+#include "uap_headers.h" -+ -+/** -+ * the global variable of a pointer to uap_private -+ * structure variable -+ */ -+uap_private *uappriv = NULL; -+#ifdef DEBUG_LEVEL1 -+#define DEFAULT_DEBUG_MASK (DBG_MSG | DBG_FATAL | DBG_ERROR) -+u32 drvdbg = DEFAULT_DEBUG_MASK; -+#endif -+/** Helper name */ -+char *helper_name = NULL; -+/** Firmware name */ -+char *fw_name = NULL; -+ -+/** Semaphore for add/remove card */ -+SEMAPHORE AddRemoveCardSem; -+ -+/******************************************************** -+ Local Functions -+********************************************************/ -+/** -+ * @brief This function send sleep confirm command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE -+ */ -+static int -+uap_dnld_sleep_confirm_cmd(uap_private * priv) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ int ret = UAP_STATUS_SUCCESS; -+ ENTER(); -+ PRINTM(CMND, "Sleep confirm\n"); -+ Adapter->cmd_pending = TRUE; -+ Adapter->cmd_wait_option = HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM; -+ ret = -+ sbi_host_to_card(priv, (u8 *) & Adapter->PSConfirmSleep, -+ sizeof(PS_CMD_ConfirmSleep)); -+ if (ret != UAP_STATUS_SUCCESS) { -+ Adapter->ps_state = PS_STATE_AWAKE; -+ Adapter->cmd_pending = FALSE; -+ Adapter->cmd_wait_option = FALSE; -+ } -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function process sleep confirm resp from firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @param resp A pointer to resp buf -+ * @param resp_len resp buf len -+ * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE -+ */ -+int -+uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ HostCmd_DS_COMMAND *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ ENTER(); -+ PRINTM(CMND, "Sleep confirm resp\n"); -+ if (!resp_len) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ cmd = (HostCmd_DS_COMMAND *) resp; -+ cmd->Result = uap_le16_to_cpu(cmd->Result); -+ if (cmd->Result != UAP_STATUS_SUCCESS) { -+ PRINTM(ERROR, "HOST_CMD_APCMD_PS_SLEEP_CONFIRM fail=%x\n", cmd->Result); -+ ret = -EFAULT; -+ } -+ done: -+ if (ret == UAP_STATUS_SUCCESS) -+ Adapter->ps_state = PS_STATE_SLEEP; -+ else -+ Adapter->ps_state = PS_STATE_AWAKE; -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function checks condition and prepares to -+ * send sleep confirm command to firmware if OK. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return n/a -+ */ -+static void -+uap_ps_cond_check(uap_private * priv) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ -+ ENTER(); -+ if (!priv->uap_dev.cmd_sent && -+ !Adapter->cmd_pending && !Adapter->IntCounter) { -+ uap_dnld_sleep_confirm_cmd(priv); -+ } else { -+ PRINTM(INFO, "Delay Sleep Confirm (%s%s%s)\n", -+ (priv->uap_dev.cmd_sent) ? "D" : "", -+ (Adapter->cmd_pending) ? "C" : "", -+ (Adapter->IntCounter) ? "I" : ""); -+ } -+ LEAVE(); -+} -+ -+/** -+ * @brief This function add cmd to cmdQ and waiting for response -+ * -+ * @param priv A pointer to uap_private structure -+ * @param skb A pointer to the skb for process -+ * @param wait_option Wait option -+ * @return UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE -+ */ -+static int -+uap_process_cmd(uap_private * priv, struct sk_buff *skb, u8 wait_option) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ int ret = UAP_STATUS_SUCCESS; -+ HostCmd_DS_COMMAND *cmd; -+ u8 *headptr; -+ ENTER(); -+ if (Adapter->HardwareStatus != HWReady) { -+ PRINTM(ERROR, "Hw not ready, uap_process_cmd\n"); -+ kfree(skb); -+ LEAVE(); -+ return -EFAULT; -+ } -+ skb->cb[0] = wait_option; -+ headptr = skb->data; -+ *(u16 *) & headptr[0] = uap_cpu_to_le16(skb->len); -+ *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_CMD); -+ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); -+ Adapter->SeqNum++; -+ cmd->SeqNum = uap_cpu_to_le16(Adapter->SeqNum); -+ PRINTM(CMND, "process_cmd: %x\n", cmd->Command); -+ DBG_HEXDUMP(CMD_D, "process_cmd", (u8 *) cmd, cmd->Size); -+ if (!wait_option) { -+ skb_queue_tail(&priv->adapter->cmd_queue, skb); -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ LEAVE(); -+ return ret; -+ } -+ if (OS_ACQ_SEMAPHORE_BLOCK(&Adapter->CmdSem)) { -+ PRINTM(ERROR, "Acquire semaphore error, uap_prepare_cmd\n"); -+ kfree(skb); -+ LEAVE(); -+ return -EBUSY; -+ } -+ skb_queue_tail(&priv->adapter->cmd_queue, skb); -+ Adapter->CmdWaitQWoken = FALSE; -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ /* Sleep until response is generated by FW */ -+ if (wait_option == HostCmd_OPTION_WAITFORRSP_TIMEOUT) { -+ if (!os_wait_interruptible_timeout -+ (Adapter->cmdwait_q, Adapter->CmdWaitQWoken, MRVDRV_TIMER_20S)) { -+ PRINTM(ERROR, "Cmd timeout\n"); -+ Adapter->cmd_pending = FALSE; -+ ret = -EFAULT; -+ } -+ } else -+ wait_event_interruptible(Adapter->cmdwait_q, Adapter->CmdWaitQWoken); -+ OS_REL_SEMAPHORE(&Adapter->CmdSem); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief Inspect the response buffer for pointers to expected TLVs -+ * -+ * -+ * @param pTlv Pointer to the start of the TLV buffer to parse -+ * @param tlvBufSize Size of the TLV buffer -+ * @param reqTlvType request tlv's tlvtype -+ * @param ppTlv Output parameter: Pointer to the request TLV if found -+ * -+ * @return void -+ */ -+static void -+uap_get_tlv_ptrs(MrvlIEtypes_Data_t * pTlv, int tlvBufSize, -+ u16 reqTlvType, MrvlIEtypes_Data_t ** ppTlv) -+{ -+ MrvlIEtypes_Data_t *pCurrentTlv; -+ int tlvBufLeft; -+ u16 tlvType; -+ u16 tlvLen; -+ -+ ENTER(); -+ pCurrentTlv = pTlv; -+ tlvBufLeft = tlvBufSize; -+ *ppTlv = NULL; -+ PRINTM(INFO, "uap_get_tlv: tlvBufSize = %d, reqTlvType=%x\n", tlvBufSize, -+ reqTlvType); -+ while (tlvBufLeft >= sizeof(MrvlIEtypesHeader_t)) { -+ tlvType = uap_le16_to_cpu(pCurrentTlv->Header.Type); -+ tlvLen = uap_le16_to_cpu(pCurrentTlv->Header.Len); -+ if (reqTlvType == tlvType) -+ *ppTlv = (MrvlIEtypes_Data_t *) pCurrentTlv; -+ if (*ppTlv) { -+ HEXDUMP("TLV Buf", (u8 *) * ppTlv, tlvLen); -+ break; -+ } -+ tlvBufLeft -= (sizeof(pTlv->Header) + tlvLen); -+ pCurrentTlv = (MrvlIEtypes_Data_t *) (pCurrentTlv->Data + tlvLen); -+ } /* while */ -+ LEAVE(); -+} -+ -+/** -+ * @brief This function get mac -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+static int -+uap_get_mac_address(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_COMMAND *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ MrvlIEtypes_MacAddr_t *pMacAddrTlv; -+ MrvlIEtypes_Data_t *pTlv; -+ u16 tlvBufSize; -+ ENTER(); -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = -+ S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t); -+ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_GET); -+ pMacAddrTlv = -+ (MrvlIEtypes_MacAddr_t *) (skb->data + INTF_HEADER_LEN + S_DS_GEN + -+ sizeof(HostCmd_SYS_CONFIG)); -+ pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID); -+ pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to process cmd SYS_CONFIGURE Query\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ if (!Adapter->CmdSize) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf; -+ cmd->Result = uap_le16_to_cpu(cmd->Result); -+ if (cmd->Result != UAP_STATUS_SUCCESS) { -+ PRINTM(ERROR, "uap_get_mac_address fail=%x\n", cmd->Result); -+ ret = -EFAULT; -+ goto done; -+ } -+ pTlv = -+ (MrvlIEtypes_Data_t *) (Adapter->CmdBuf + S_DS_GEN + -+ sizeof(HostCmd_SYS_CONFIG)); -+ tlvBufSize = Adapter->CmdSize - S_DS_GEN - sizeof(HostCmd_SYS_CONFIG); -+ uap_get_tlv_ptrs(pTlv, tlvBufSize, MRVL_AP_MAC_ADDRESS_TLV_ID, -+ (MrvlIEtypes_Data_t **) & pMacAddrTlv); -+ if (pMacAddrTlv) { -+ memcpy(priv->uap_dev.netdev->dev_addr, pMacAddrTlv->ApMacAddr, -+ ETH_ALEN); -+ HEXDUMP("Original MAC addr", priv->uap_dev.netdev->dev_addr, ETH_ALEN); -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function checks the conditions and sends packet to device -+ * -+ * @param priv A pointer to uap_private structure -+ * @param skb A pointer to the skb for process -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_process_tx(uap_private * priv, struct sk_buff *skb) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ int ret = UAP_STATUS_SUCCESS; -+ TxPD *pLocalTxPD; -+ u8 *headptr; -+ struct sk_buff *newskb; -+ int newheadlen; -+ ENTER(); -+ ASSERT(skb); -+ if (!skb) { -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ if (skb_headroom(skb) < (sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT)) { -+ newheadlen = sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT; -+ PRINTM(WARN, "Tx: Insufficient skb headroom %d\n", skb_headroom(skb)); -+ /* Insufficient skb headroom - allocate a new skb */ -+ newskb = skb_realloc_headroom(skb, newheadlen); -+ if (unlikely(newskb == NULL)) { -+ PRINTM(ERROR, "Tx: Cannot allocate skb\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ kfree_skb(skb); -+ skb = newskb; -+ PRINTM(INFO, "new skb headroom %d\n", skb_headroom(skb)); -+ } -+ /* headptr should be aligned */ -+ headptr = skb->data - sizeof(TxPD) - INTF_HEADER_LEN; -+ headptr = (u8 *) ((u32) headptr & ~((u32) (HEADER_ALIGNMENT - 1))); -+ -+ pLocalTxPD = (TxPD *) (headptr + INTF_HEADER_LEN); -+ memset(pLocalTxPD, 0, sizeof(TxPD)); -+ pLocalTxPD->BssType = PKT_TYPE_MICROAP; -+ pLocalTxPD->TxPktLength = skb->len; -+ /* offset of actual data */ -+ pLocalTxPD->TxPktOffset = (long) skb->data - (long) pLocalTxPD; -+ endian_convert_TxPD(pLocalTxPD); -+ *(u16 *) & headptr[0] = -+ uap_cpu_to_le16(skb->len + ((long) skb->data - (long) headptr)); -+ *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_DAT); -+ ret = -+ sbi_host_to_card(priv, headptr, -+ skb->len + ((long) skb->data - (long) headptr)); -+ if (ret) { -+ PRINTM(ERROR, "uap_process_tx Error: sbi_host_to_card failed: 0x%X\n", -+ ret); -+ Adapter->dbg.num_tx_host_to_card_failure++; -+ goto done; -+ } -+ PRINTM(DATA, "Data => FW\n"); -+ DBG_HEXDUMP(DAT_D, "Tx", headptr, -+ MIN(skb->len + sizeof(TxPD), DATA_DUMP_LEN)); -+ done: -+ /* Freed skb */ -+ kfree_skb(skb); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function initializes the adapter structure -+ * and set default value to the member of adapter. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_init_sw(uap_private * priv) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ -+ ENTER(); -+ -+ if (!(Adapter->CmdBuf = kmalloc(MRVDRV_SIZE_OF_CMD_BUFFER, GFP_KERNEL))) { -+ PRINTM(INFO, "Failed to allocate command buffer!\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ Adapter->cmd_pending = FALSE; -+ Adapter->CmdWaitQWoken = FALSE; -+ Adapter->ps_state = PS_STATE_AWAKE; -+ Adapter->WakeupTries = 0; -+ -+ memset(&Adapter->PSConfirmSleep, 0, sizeof(PS_CMD_ConfirmSleep)); -+ /** SDIO header */ -+ Adapter->PSConfirmSleep.SDLen = -+ uap_cpu_to_le16(sizeof(PS_CMD_ConfirmSleep)); -+ Adapter->PSConfirmSleep.SDType = uap_cpu_to_le16(MV_TYPE_CMD); -+ Adapter->PSConfirmSleep.SeqNum = 0; -+ Adapter->PSConfirmSleep.Command = uap_cpu_to_le16(HOST_CMD_SLEEP_CONFIRM); -+ Adapter->PSConfirmSleep.Size = uap_cpu_to_le16(sizeof(HostCmd_DS_GEN)); -+ Adapter->PSConfirmSleep.Result = 0; -+ -+ init_waitqueue_head(&Adapter->cmdwait_q); -+ OS_INIT_SEMAPHORE(&Adapter->CmdSem); -+ -+ skb_queue_head_init(&Adapter->tx_queue); -+ skb_queue_head_init(&Adapter->cmd_queue); -+ -+ /* Status variable */ -+ Adapter->HardwareStatus = HWInitializing; -+ -+ /* PnP support */ -+ Adapter->SurpriseRemoved = FALSE; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) -+ Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL, -+ NL_MULTICAST_GROUP, NULL, -+ THIS_MODULE); -+#else -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) -+ Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL, -+ NL_MULTICAST_GROUP, NULL, NULL, -+ THIS_MODULE); -+#else -+ Adapter->nl_sk = netlink_kernel_create(&init_net, NETLINK_MARVELL, -+ NL_MULTICAST_GROUP, NULL, NULL, -+ THIS_MODULE); -+#endif -+#endif -+ if (!Adapter->nl_sk) { -+ PRINTM(ERROR, -+ "Could not initialize netlink event passing mechanism!\n"); -+ } -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function sends FUNC_INIT command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+static int -+uap_func_init(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_GEN *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ ENTER(); -+ if (Adapter->HardwareStatus != HWReady) { -+ PRINTM(ERROR, "uap_func_init:Hardware is not ready!\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = sizeof(HostCmd_DS_GEN); -+ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_INIT); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "HostCmd_CMD_FUNC_INIT\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_INIT\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function sends FUNC_SHUTDOWN command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+static int __exit -+uap_func_shutdown(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_GEN *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ ENTER(); -+ if (Adapter->HardwareStatus != HWReady) { -+ PRINTM(ERROR, "uap_func_shutdown:Hardware is not ready!\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = sizeof(HostCmd_DS_GEN); -+ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_SHUTDOWN); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "HostCmd_CMD_FUNC_SHUTDOWN\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_SHUTDOWN\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function initializes firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_init_fw(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ ENTER(); -+ sbi_disable_host_int(priv); -+ /* Check if firmware is already running */ -+ if (sbi_check_fw_status(priv, 1) == UAP_STATUS_SUCCESS) { -+ PRINTM(MSG, "UAP FW already running! Skip FW download\n"); -+ } else { -+ if ((ret = request_firmware(&priv->fw_helper, helper_name, -+ priv->hotplug_device)) < 0) { -+ PRINTM(FATAL, -+ "request_firmware() failed (helper), error code = %#x\n", -+ ret); -+ goto done; -+ } -+ -+ /* Download the helper */ -+ ret = sbi_prog_helper(priv); -+ -+ if (ret) { -+ PRINTM(FATAL, -+ "Bootloader in invalid state! Helper download failed!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ if ((ret = request_firmware(&priv->firmware, fw_name, -+ priv->hotplug_device)) < 0) { -+ PRINTM(FATAL, "request_firmware() failed, error code = %#x\n", ret); -+ goto done; -+ } -+ -+ /* Download the main firmware via the helper firmware */ -+ if (sbi_prog_fw_w_helper(priv)) { -+ PRINTM(FATAL, "UAP FW download failed!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ /* Check if the firmware is downloaded successfully or not */ -+ if (sbi_check_fw_status(priv, MAX_FIRMWARE_POLL_TRIES) == -+ UAP_STATUS_FAILURE) { -+ PRINTM(FATAL, "FW failed to be active in time!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ PRINTM(MSG, "UAP FW is active\n"); -+ } -+ sbi_enable_host_int(priv); -+ priv->adapter->HardwareStatus = HWReady; -+ if (uap_func_init(priv) != UAP_STATUS_SUCCESS) { -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ done: -+ if (priv->fw_helper) -+ release_firmware(priv->fw_helper); -+ if (priv->firmware) -+ release_firmware(priv->firmware); -+ LEAVE(); -+ return ret; -+ -+} -+ -+/** -+ * @brief This function frees the structure of adapter -+ * -+ * @param priv A pointer to uap_private structure -+ * @return n/a -+ */ -+static void -+uap_free_adapter(uap_private * priv) -+{ -+ uap_adapter *Adapter = priv->adapter; -+ -+ ENTER(); -+ -+ if (Adapter) { -+ if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) { -+ sock_release((Adapter->nl_sk)->sk_socket); -+ Adapter->nl_sk = NULL; -+ } -+ if (Adapter->CmdBuf) -+ kfree(Adapter->CmdBuf); -+ skb_queue_purge(&priv->adapter->tx_queue); -+ skb_queue_purge(&priv->adapter->cmd_queue); -+ /* Free the adapter object itself */ -+ kfree(Adapter); -+ priv->adapter = NULL; -+ } -+ -+ LEAVE(); -+} -+ -+/** -+ * @brief This function handles the major job in uap driver. -+ * it handles the event generated by firmware, rx data received -+ * from firmware and tx data sent from kernel. -+ * -+ * @param data A pointer to uap_thread structure -+ * @return BT_STATUS_SUCCESS -+ */ -+static int -+uap_service_main_thread(void *data) -+{ -+ uap_thread *thread = data; -+ uap_private *priv = thread->priv; -+ uap_adapter *Adapter = priv->adapter; -+ wait_queue_t wait; -+ u8 ireg = 0; -+ struct sk_buff *skb; -+ ENTER(); -+ uap_activate_thread(thread); -+ init_waitqueue_entry(&wait, current); -+ current->flags |= PF_NOFREEZE; -+ -+ for (;;) { -+ add_wait_queue(&thread->waitQ, &wait); -+ OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE); -+ if ((Adapter->WakeupTries) || -+ (!Adapter->IntCounter && Adapter->ps_state == PS_STATE_PRE_SLEEP) || -+ (!priv->adapter->IntCounter -+ && (priv->uap_dev.data_sent || -+ skb_queue_empty(&priv->adapter->tx_queue)) -+ && (priv->uap_dev.cmd_sent || Adapter->cmd_pending || -+ skb_queue_empty(&priv->adapter->cmd_queue)) -+ )) { -+ PRINTM(INFO, "Main: Thread sleeping...\n"); -+ schedule(); -+ } -+ OS_SET_THREAD_STATE(TASK_RUNNING); -+ remove_wait_queue(&thread->waitQ, &wait); -+ if (kthread_should_stop() || Adapter->SurpriseRemoved) { -+ PRINTM(INFO, "main-thread: break from main thread: " -+ "SurpriseRemoved=0x%x\n", Adapter->SurpriseRemoved); -+ /* Cancel pending command */ -+ if (Adapter->cmd_pending == TRUE) { -+ /* Wake up cmd Q */ -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ } -+ break; -+ } -+ -+ PRINTM(INFO, "Main: Thread waking up...\n"); -+ if (priv->adapter->IntCounter) { -+ OS_INT_DISABLE; -+ Adapter->IntCounter = 0; -+ OS_INT_RESTORE; -+ sbi_get_int_status(priv, &ireg); -+ } else if ((priv->adapter->ps_state == PS_STATE_SLEEP) && -+ (!skb_queue_empty(&priv->adapter->cmd_queue) || -+ !skb_queue_empty(&priv->adapter->tx_queue))) { -+ priv->adapter->WakeupTries++; -+ PRINTM(CMND, "%lu : Wakeup device...\n", os_time_get()); -+ sbi_wakeup_firmware(priv); -+ continue; -+ } -+ if (Adapter->ps_state == PS_STATE_PRE_SLEEP) -+ uap_ps_cond_check(priv); -+ -+ /* The PS state is changed during processing of Sleep Request event -+ above */ -+ if ((Adapter->ps_state == PS_STATE_SLEEP) || -+ (Adapter->ps_state == PS_STATE_PRE_SLEEP)) -+ continue; -+ /* Execute the next command */ -+ if (!priv->uap_dev.cmd_sent && !Adapter->cmd_pending && -+ (Adapter->HardwareStatus == HWReady)) { -+ if (!skb_queue_empty(&priv->adapter->cmd_queue)) { -+ skb = skb_dequeue(&priv->adapter->cmd_queue); -+ if (skb) { -+ Adapter->CmdSize = 0; -+ Adapter->cmd_pending = TRUE; -+ Adapter->cmd_wait_option = skb->cb[0]; -+ if (sbi_host_to_card(priv, skb->data, skb->len)) { -+ PRINTM(ERROR, "Cmd:sbi_host_to_card failed!\n"); -+ Adapter->cmd_pending = FALSE; -+ Adapter->dbg.num_cmd_host_to_card_failure++; -+ /* Wake up cmd Q */ -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ } else { -+ if (Adapter->cmd_wait_option == -+ HostCmd_OPTION_WAITFORSEND) { -+ /* Wake up cmd Q */ -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ Adapter->cmd_wait_option = FALSE; -+ } -+ } -+ kfree_skb(skb); -+ } -+ } -+ } -+ if (!priv->uap_dev.data_sent && (Adapter->HardwareStatus == HWReady)) { -+ if (!skb_queue_empty(&priv->adapter->tx_queue)) { -+ skb = skb_dequeue(&priv->adapter->tx_queue); -+ if (skb) { -+ if (uap_process_tx(priv, skb)) { -+ priv->stats.tx_dropped++; -+ priv->stats.tx_errors++; -+ os_start_queue(priv); -+ } else { -+ priv->stats.tx_packets++; -+ priv->stats.tx_bytes += skb->len; -+ } -+ -+ } -+ } -+ } -+ } -+ uap_deactivate_thread(thread); -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief uap hostcmd ioctl handler -+ * -+ * @param dev A pointer to net_device structure -+ * @param req A pointer to ifreq structure -+ * @return UAP_STATUS_SUCCESS --success, otherwise fail -+ */ -+/********* format of ifr_data *************/ -+/* buf_len + Hostcmd_body */ -+/* buf_len: 4 bytes */ -+/* the length of the buf which */ -+/* can be used to return data */ -+/* to application */ -+/* Hostcmd_body */ -+/*******************************************/ -+static int -+uap_hostcmd_ioctl(struct net_device *dev, struct ifreq *req) -+{ -+ u32 buf_len; -+ HostCmd_HEADER head; -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ uap_adapter *Adapter = priv->adapter; -+ int ret = UAP_STATUS_SUCCESS; -+ struct sk_buff *skb; -+ -+ ENTER(); -+ -+ /* Sanity check */ -+ if (req->ifr_data == NULL) { -+ PRINTM(ERROR, "uap_hostcmd_ioctl() corrupt data\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ if (copy_from_user(&buf_len, req->ifr_data, sizeof(buf_len))) { -+ PRINTM(ERROR, "Copy from user failed\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ memset(&head, 0, sizeof(HostCmd_HEADER)); -+ /* Get the command size from user space */ -+ if (copy_from_user -+ (&head, req->ifr_data + sizeof(buf_len), sizeof(HostCmd_HEADER))) { -+ PRINTM(ERROR, "Copy from user failed\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ head.Size = uap_le16_to_cpu(head.Size); -+ if (head.Size > MRVDRV_SIZE_OF_CMD_BUFFER) { -+ PRINTM(ERROR, "CmdSize too big=%d\n", head.Size); -+ LEAVE(); -+ return -EFAULT; -+ } -+ PRINTM(CMND, "ioctl: hostcmd=%x, size=%d,buf_len=%d\n", head.Command, -+ head.Size, buf_len); -+ skb = dev_alloc_skb(head.Size + INTF_HEADER_LEN); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ LEAVE(); -+ return -ENOMEM; -+ } -+ -+ /* Get the command from user space */ -+ if (copy_from_user -+ (skb->data + INTF_HEADER_LEN, req->ifr_data + sizeof(buf_len), -+ head.Size)) { -+ PRINTM(ERROR, "Copy from user failed\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ skb_put(skb, head.Size + INTF_HEADER_LEN); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) { -+ PRINTM(ERROR, "Fail to process cmd\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ if (!Adapter->CmdSize) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ if (Adapter->CmdSize > buf_len) { -+ PRINTM(ERROR, "buf_len is too small\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ /* Copy to user */ -+ if (copy_to_user -+ (req->ifr_data + sizeof(buf_len), Adapter->CmdBuf, Adapter->CmdSize)) { -+ PRINTM(ERROR, "Copy to user failed!\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief uap power mode ioctl handler -+ * -+ * @param dev A pointer to net_device structure -+ * @param req A pointer to ifreq structure -+ * @return UAP_STATUS_SUCCESS --success, otherwise fail -+ */ -+static int -+uap_power_mode_ioctl(struct net_device *dev, struct ifreq *req) -+{ -+ ps_mgmt pm_cfg; -+ int ret = UAP_STATUS_SUCCESS; -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb = NULL; -+ HostCmd_DS_COMMAND *cmd; -+ u32 CmdSize; -+ u8 *tlv = NULL; -+ MrvlIEtypes_sleep_param_t *sleep_tlv = NULL; -+ MrvlIEtypes_inact_sleep_param_t *inact_tlv = NULL; -+ u16 tlv_buf_left = 0; -+ MrvlIEtypesHeader_t *tlvbuf = NULL; -+ u16 tlv_type = 0; -+ u16 tlv_len = 0; -+ -+ ENTER(); -+ -+ /* Sanity check */ -+ if (req->ifr_data == NULL) { -+ PRINTM(ERROR, "uap_power_mode_ioctl() corrupt data\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ -+ memset(&pm_cfg, 0, sizeof(ps_mgmt)); -+ if (copy_from_user(&pm_cfg, req->ifr_data, sizeof(ps_mgmt))) { -+ PRINTM(ERROR, "Copy from user failed\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ PRINTM(CMND, -+ "ioctl power: flag=0x%x ps_mode=%d ctrl_bitmap=%d min_sleep=%d max_sleep=%d " -+ "inact_to=%d min_awake=%d max_awake=%d\n", pm_cfg.flags, -+ (int) pm_cfg.ps_mode, (int) pm_cfg.sleep_param.ctrl_bitmap, -+ (int) pm_cfg.sleep_param.min_sleep, -+ (int) pm_cfg.sleep_param.max_sleep, -+ (int) pm_cfg.inact_param.inactivity_to, -+ (int) pm_cfg.inact_param.min_awake, -+ (int) pm_cfg.inact_param.max_awake); -+ -+ if (pm_cfg. -+ flags & ~(PS_FLAG_PS_MODE | PS_FLAG_SLEEP_PARAM | -+ PS_FLAG_INACT_SLEEP_PARAM)) { -+ PRINTM(ERROR, "Invalid parameter: flags = 0x%x\n", pm_cfg.flags); -+ ret = -EINVAL; -+ goto done; -+ } -+ if (pm_cfg.ps_mode > PS_MODE_INACTIVITY) { -+ PRINTM(ERROR, "Invalid parameter: ps_mode = %d\n", (int) pm_cfg.flags); -+ ret = -EINVAL; -+ goto done; -+ } -+ -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(INFO, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ -+ CmdSize = S_DS_GEN + sizeof(HostCmd_DS_POWER_MGMT_EXT); -+ -+ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_POWER_MGMT_EXT); -+ if (!pm_cfg.flags) { -+ cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_GET); -+ } else { -+ cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_SET); -+ cmd->params.pm_cfg.power_mode = uap_cpu_to_le16(pm_cfg.ps_mode); -+ tlv = (u8 *) & cmd->params.pm_cfg + sizeof(HostCmd_DS_POWER_MGMT_EXT); -+ -+ if ((pm_cfg.ps_mode) && (pm_cfg.flags & PS_FLAG_SLEEP_PARAM)) { -+ sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlv; -+ sleep_tlv->header.Type = uap_cpu_to_le16(TLV_TYPE_AP_SLEEP_PARAM); -+ sleep_tlv->header.Len = -+ uap_cpu_to_le16(sizeof(MrvlIEtypes_sleep_param_t) - -+ sizeof(MrvlIEtypesHeader_t)); -+ sleep_tlv->ctrl_bitmap = -+ uap_cpu_to_le32(pm_cfg.sleep_param.ctrl_bitmap); -+ sleep_tlv->min_sleep = -+ uap_cpu_to_le32(pm_cfg.sleep_param.min_sleep); -+ sleep_tlv->max_sleep = -+ uap_cpu_to_le32(pm_cfg.sleep_param.max_sleep); -+ CmdSize += sizeof(MrvlIEtypes_sleep_param_t); -+ tlv += sizeof(MrvlIEtypes_sleep_param_t); -+ } -+ if ((pm_cfg.ps_mode == PS_MODE_INACTIVITY) && -+ (pm_cfg.flags & PS_FLAG_INACT_SLEEP_PARAM)) { -+ inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlv; -+ inact_tlv->header.Type = -+ uap_cpu_to_le16(TLV_TYPE_AP_INACT_SLEEP_PARAM); -+ inact_tlv->header.Len = -+ uap_cpu_to_le16(sizeof(MrvlIEtypes_inact_sleep_param_t) - -+ sizeof(MrvlIEtypesHeader_t)); -+ inact_tlv->inactivity_to = -+ uap_cpu_to_le32(pm_cfg.inact_param.inactivity_to); -+ inact_tlv->min_awake = -+ uap_cpu_to_le32(pm_cfg.inact_param.min_awake); -+ inact_tlv->max_awake = -+ uap_cpu_to_le32(pm_cfg.inact_param.max_awake); -+ CmdSize += sizeof(MrvlIEtypes_inact_sleep_param_t); -+ tlv += sizeof(MrvlIEtypes_inact_sleep_param_t); -+ } -+ } -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) { -+ PRINTM(ERROR, "Fail to process cmd POWER_MODE\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ if (!Adapter->CmdSize) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf; -+ cmd->Result = uap_le16_to_cpu(cmd->Result); -+ if (cmd->Result != UAP_STATUS_SUCCESS) { -+ PRINTM(ERROR, "HOST_CMD_APCMD_POWER_MODE fail=%x\n", cmd->Result); -+ ret = -EFAULT; -+ goto done; -+ } -+ if (pm_cfg.flags) { -+ Adapter->psmode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode); -+ } else { -+ pm_cfg.flags = PS_FLAG_PS_MODE; -+ pm_cfg.ps_mode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode); -+ tlv_buf_left = -+ cmd->Size - (sizeof(HostCmd_DS_POWER_MGMT_EXT) + S_DS_GEN); -+ tlvbuf = -+ (MrvlIEtypesHeader_t *) ((u8 *) & cmd->params.pm_cfg + -+ sizeof(HostCmd_DS_POWER_MGMT_EXT)); -+ while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) { -+ tlv_type = uap_le16_to_cpu(tlvbuf->Type); -+ tlv_len = uap_le16_to_cpu(tlvbuf->Len); -+ switch (tlv_type) { -+ case TLV_TYPE_AP_SLEEP_PARAM: -+ sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlvbuf; -+ pm_cfg.flags |= PS_FLAG_SLEEP_PARAM; -+ pm_cfg.sleep_param.ctrl_bitmap = -+ uap_le32_to_cpu(sleep_tlv->ctrl_bitmap); -+ pm_cfg.sleep_param.min_sleep = -+ uap_le32_to_cpu(sleep_tlv->min_sleep); -+ pm_cfg.sleep_param.max_sleep = -+ uap_le32_to_cpu(sleep_tlv->max_sleep); -+ break; -+ case TLV_TYPE_AP_INACT_SLEEP_PARAM: -+ inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlvbuf; -+ pm_cfg.flags |= PS_FLAG_INACT_SLEEP_PARAM; -+ pm_cfg.inact_param.inactivity_to = -+ uap_le32_to_cpu(inact_tlv->inactivity_to); -+ pm_cfg.inact_param.min_awake = -+ uap_le32_to_cpu(inact_tlv->min_awake); -+ pm_cfg.inact_param.max_awake = -+ uap_le32_to_cpu(inact_tlv->max_awake); -+ break; -+ } -+ tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t); -+ tlvbuf = -+ (MrvlIEtypesHeader_t *) ((u8 *) tlvbuf + tlv_len + -+ sizeof(MrvlIEtypesHeader_t)); -+ } -+ /* Copy to user */ -+ if (copy_to_user(req->ifr_data, &pm_cfg, sizeof(ps_mgmt))) { -+ PRINTM(ERROR, "Copy to user failed!\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function send bss_stop command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+static int -+uap_bss_stop(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_GEN *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ ENTER(); -+ if (Adapter->HardwareStatus != HWReady) { -+ PRINTM(ERROR, "uap_bss_stop:Hardware is not ready!\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = sizeof(HostCmd_DS_GEN); -+ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_BSS_STOP); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "APCMD_BSS_STOP\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to process cmd BSS_STOP\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/******************************************************** -+ Global Functions -+********************************************************/ -+/** -+ * @brief This function send soft_reset command to firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS on success, otherwise failure code -+ */ -+int -+uap_soft_reset(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u32 CmdSize; -+ HostCmd_DS_GEN *cmd; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ ENTER(); -+ ret = uap_bss_stop(priv); -+ if (ret != UAP_STATUS_SUCCESS) -+ goto done; -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ ret = -ENOMEM; -+ goto done; -+ } -+ CmdSize = sizeof(HostCmd_DS_GEN); -+ cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SOFT_RESET); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "APCMD_SOFT_RESET\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORSEND)) { -+ PRINTM(ERROR, "Fail to process cmd SOFT_RESET\n"); -+ ret = -EFAULT; -+ goto done; -+ } -+ Adapter->SurpriseRemoved = TRUE; -+ /* delay to allow hardware complete reset */ -+ os_sched_timeout(5); -+ if (priv->MediaConnected == TRUE) { -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ priv->MediaConnected = FALSE; -+ } -+ Adapter->CmdSize = 0; -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ skb_queue_purge(&priv->adapter->tx_queue); -+ skb_queue_purge(&priv->adapter->cmd_queue); -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function processes received packet and forwards it -+ * to kernel/upper layer -+ * -+ * @param priv A pointer to uap_private -+ * @param skb A pointer to skb which includes the received packet -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+uap_process_rx_packet(uap_private * priv, struct sk_buff *skb) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ RxPD *pRxPD; -+ ENTER(); -+ priv->adapter->ps_state = PS_STATE_AWAKE; -+ pRxPD = (RxPD *) skb->data; -+ endian_convert_RxPD(pRxPD); -+ DBG_HEXDUMP(DAT_D, "Rx", skb->data, MIN(skb->len, DATA_DUMP_LEN)); -+ skb_pull(skb, pRxPD->RxPktOffset); -+ priv->stats.rx_packets++; -+ priv->stats.rx_bytes += skb->len; -+ os_upload_rx_packet(priv, skb); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function opens the network device -+ * -+ * @param dev A pointer to net_device structure -+ * @return UAP_STATUS_SUCCESS -+ */ -+static int -+uap_open(struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) (uap_private *) netdev_priv(dev); -+ uap_adapter *Adapter = priv->adapter; -+ int i = 0; -+ -+ ENTER(); -+ -+ /* On some systems the device open handler will be called before HW ready. */ -+ /* Use the following flag check and wait function to work around the issue. */ -+ while ((Adapter->HardwareStatus != HWReady) && -+ (i < MAX_WAIT_DEVICE_READY_COUNT)) { -+ i++; -+ os_sched_timeout(100); -+ } -+ if (i >= MAX_WAIT_DEVICE_READY_COUNT) { -+ PRINTM(FATAL, "HW not ready, uap_open() return failure\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ if (MODULE_GET == 0) -+ return UAP_STATUS_FAILURE; -+ -+ priv->open = TRUE; -+ if (priv->MediaConnected == TRUE) { -+ os_carrier_on(priv); -+ os_start_queue(priv); -+ } else { -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ } -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function closes the network device -+ * -+ * @param dev A pointer to net_device structure -+ * @return UAP_STATUS_SUCCESS -+ */ -+static int -+uap_close(struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ -+ ENTER(); -+ skb_queue_purge(&priv->adapter->tx_queue); -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ -+ MODULE_PUT; -+ priv->open = FALSE; -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function returns the network statistics -+ * -+ * @param dev A pointer to uap_private structure -+ * @return A pointer to net_device_stats structure -+ */ -+static struct net_device_stats * -+uap_get_stats(struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ -+ return &priv->stats; -+} -+ -+/** -+ * @brief This function sets the MAC address to firmware. -+ * -+ * @param dev A pointer to uap_private structure -+ * @param addr MAC address to set -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_set_mac_address(struct net_device *dev, void *addr) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ struct sockaddr *pHwAddr = (struct sockaddr *) addr; -+ u32 CmdSize; -+ HostCmd_DS_COMMAND *cmd; -+ MrvlIEtypes_MacAddr_t *pMacAddrTlv; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb; -+ -+ ENTER(); -+ -+ /* Dump MAC address */ -+ DBG_HEXDUMP(CMD_D, "Original MAC addr", dev->dev_addr, ETH_ALEN); -+ DBG_HEXDUMP(CMD_D, "New MAC addr", pHwAddr->sa_data, ETH_ALEN); -+ if (priv->open && (priv->MediaConnected == TRUE)) { -+ os_carrier_on(priv); -+ os_start_queue(priv); -+ } -+ skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER); -+ if (!skb) { -+ PRINTM(ERROR, "No free skb\n"); -+ LEAVE(); -+ return -ENOMEM; -+ } -+ CmdSize = -+ S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t); -+ cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN); -+ cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE); -+ cmd->Size = uap_cpu_to_le16(CmdSize); -+ cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_SET); -+ pMacAddrTlv = -+ (MrvlIEtypes_MacAddr_t *) ((u8 *) cmd + S_DS_GEN + -+ sizeof(HostCmd_SYS_CONFIG)); -+ pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID); -+ pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN); -+ memcpy(pMacAddrTlv->ApMacAddr, pHwAddr->sa_data, ETH_ALEN); -+ skb_put(skb, CmdSize + INTF_HEADER_LEN); -+ PRINTM(CMND, "set_mac_address\n"); -+ if (UAP_STATUS_SUCCESS != -+ uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) { -+ PRINTM(ERROR, "Fail to set mac address\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ if (!Adapter->CmdSize) { -+ PRINTM(ERROR, "Cmd Size is 0\n"); -+ LEAVE(); -+ return -EFAULT; -+ } -+ cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf; -+ cmd->Result = uap_cpu_to_le16(cmd->Result); -+ if (cmd->Result != UAP_STATUS_SUCCESS) { -+ PRINTM(ERROR, "set mac addrress fail,cmd result=%x\n", cmd->Result); -+ ret = -EFAULT; -+ } else -+ memcpy(dev->dev_addr, pHwAddr->sa_data, ETH_ALEN); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function handles the timeout of packet -+ * transmission -+ * -+ * @param dev A pointer to net_device structure -+ * @return n/a -+ */ -+static void -+uap_tx_timeout(struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ -+ ENTER(); -+ -+ PRINTM(DATA, "Tx timeout\n"); -+ UpdateTransStart(dev); -+ priv->num_tx_timeout++; -+ priv->adapter->IntCounter++; -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ -+ LEAVE(); -+} -+ -+/** -+ * @brief This function handles packet transmission -+ * -+ * @param skb A pointer to sk_buff structure -+ * @param dev A pointer to net_device structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ uap_private *priv = (uap_private *) netdev_priv(dev); -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ PRINTM(DATA, "Data <= kernel\n"); -+ DBG_HEXDUMP(DAT_D, "Tx", skb->data, MIN(skb->len, DATA_DUMP_LEN)); -+ /* skb sanity check */ -+ if (!skb->len || (skb->len > MRVDRV_MAXIMUM_ETH_PACKET_SIZE)) { -+ PRINTM(ERROR, "Tx Error: Bad skb length %d : %d\n", skb->len, -+ MRVDRV_MAXIMUM_ETH_PACKET_SIZE); -+ priv->stats.tx_dropped++; -+ kfree(skb); -+ goto done; -+ } -+ skb_queue_tail(&priv->adapter->tx_queue, skb); -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ if (skb_queue_len(&priv->adapter->tx_queue) > TX_HIGH_WATERMARK) { -+ UpdateTransStart(dev); -+ os_stop_queue(priv); -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief ioctl function - entry point -+ * -+ * @param dev A pointer to net_device structure -+ * @param req A pointer to ifreq structure -+ * @param cmd command -+ * @return UAP_STATUS_SUCCESS--success, otherwise fail -+ */ -+static int -+uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ PRINTM(CMND, "uap_do_ioctl: ioctl cmd = 0x%x\n", cmd); -+ -+ switch (cmd) { -+ case UAPHOSTCMD: -+ ret = uap_hostcmd_ioctl(dev, req); -+ break; -+ case UAP_POWER_MODE: -+ ret = uap_power_mode_ioctl(dev, req); -+ break; -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function handles events generated by firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @param payload A pointer to payload buffer -+ * @param len Length of the payload -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+uap_process_event(uap_private * priv, u8 * payload, uint len) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ uap_adapter *Adapter = priv->adapter; -+ struct sk_buff *skb = NULL; -+ struct nlmsghdr *nlh = NULL; -+ struct sock *sk = Adapter->nl_sk; -+ AP_Event *pEvent; -+ -+ ENTER(); -+ Adapter->ps_state = PS_STATE_AWAKE; -+ if (len > NL_MAX_PAYLOAD) { -+ PRINTM(ERROR, "event size is too big!!! len=%d\n", len); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ pEvent = (AP_Event *) payload; -+ PRINTM(CMND, "Event: %d\n", pEvent->EventId); -+ switch (pEvent->EventId) { -+ case MICRO_AP_EV_ID_BSS_START: -+ memcpy(priv->uap_dev.netdev->dev_addr, pEvent->MacAddr, ETH_ALEN); -+ DBG_HEXDUMP(CMD_D, "BSS MAC addr", priv->uap_dev.netdev->dev_addr, -+ ETH_ALEN); -+ break; -+ case MICRO_AP_EV_BSS_ACTIVE: -+ // carrier on -+ priv->MediaConnected = TRUE; -+ os_carrier_on(priv); -+ os_start_queue(priv); -+ break; -+ case MICRO_AP_EV_BSS_IDLE: -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ priv->MediaConnected = FALSE; -+ break; -+ case EVENT_PS_AWAKE: -+ PRINTM(CMND, "UAP: PS_AWAKE\n"); -+ Adapter->ps_state = PS_STATE_AWAKE; -+ Adapter->WakeupTries = 0; -+ break; -+ case EVENT_PS_SLEEP: -+ PRINTM(CMND, "UAP: PS_SLEEP\n"); -+ Adapter->ps_state = PS_STATE_PRE_SLEEP; -+ break; -+ default: -+ break; -+ } -+ if ((pEvent->EventId == EVENT_PS_AWAKE) || -+ (pEvent->EventId == EVENT_PS_SLEEP)) -+ goto done; -+ if (sk) { -+ /* Allocate skb */ -+ if (!(skb = alloc_skb(NLMSG_SPACE(NL_MAX_PAYLOAD), GFP_ATOMIC))) { -+ PRINTM(ERROR, "Could not allocate skb for netlink.\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ nlh = (struct nlmsghdr *) skb->data; -+ nlh->nlmsg_len = NLMSG_SPACE(len); -+ -+ /* From kernel */ -+ nlh->nlmsg_pid = 0; -+ nlh->nlmsg_flags = 0; -+ -+ /* Data */ -+ skb_put(skb, nlh->nlmsg_len); -+ memcpy(NLMSG_DATA(nlh), payload, len); -+ -+ /* From Kernel */ -+ NETLINK_CB(skb).pid = 0; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ /* Multicast message */ -+ NETLINK_CB(skb).dst_pid = 0; -+#endif -+ -+ /* Multicast group number */ -+ NETLINK_CB(skb).dst_group = NL_MULTICAST_GROUP; -+ -+ /* Send message */ -+ netlink_broadcast(sk, skb, 0, NL_MULTICAST_GROUP, GFP_KERNEL); -+ -+ ret = UAP_STATUS_SUCCESS; -+ } else { -+ PRINTM(ERROR, "Could not send event through NETLINK. Link down.\n"); -+ ret = UAP_STATUS_FAILURE; -+ } -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function handles the interrupt. it will change PS -+ * state if applicable. it will wake up main_thread to handle -+ * the interrupt event as well. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return n/a -+ */ -+void -+uap_interrupt(uap_private * priv) -+{ -+ ENTER(); -+ priv->adapter->IntCounter++; -+ priv->adapter->WakeupTries = 0; -+ PRINTM(INFO, "*\n"); -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ -+ LEAVE(); -+ -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) -+/** Network device handlers */ -+static const struct net_device_ops uap_netdev_ops = { -+ .ndo_open = uap_open, -+ .ndo_start_xmit = uap_hard_start_xmit, -+ .ndo_stop = uap_close, -+ .ndo_do_ioctl = uap_do_ioctl, -+ .ndo_set_mac_address = uap_set_mac_address, -+ .ndo_tx_timeout = uap_tx_timeout, -+ .ndo_get_stats = uap_get_stats, -+}; -+#endif -+ -+/** -+ * @brief This function adds the card. it will probe the -+ * card, allocate the uap_priv and initialize the device. -+ * -+ * @param card A pointer to card -+ * @return A pointer to uap_private structure -+ */ -+uap_private * -+uap_add_card(void *card) -+{ -+ struct net_device *dev = NULL; -+ uap_private *priv = NULL; -+ -+ ENTER(); -+ -+ if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) -+ goto exit_sem_err; -+ -+ /* Allocate an Ethernet device */ -+ if (!(dev = alloc_etherdev(sizeof(uap_private)))) { -+ PRINTM(FATAL, "Init ethernet device failed!\n"); -+ goto error; -+ } -+ priv = (uap_private *) netdev_priv(dev); -+ -+ /* Allocate name */ -+ if (dev_alloc_name(dev, "uap%d") < 0) { -+ PRINTM(ERROR, "Could not allocate device name!\n"); -+ goto error; -+ } -+ -+ /* Allocate buffer for uap_adapter */ -+ if (!(priv->adapter = kmalloc(sizeof(uap_adapter), GFP_KERNEL))) { -+ PRINTM(FATAL, "Allocate buffer for uap_adapter failed!\n"); -+ goto error; -+ } -+ memset(priv->adapter, 0, sizeof(uap_adapter)); -+ -+ priv->uap_dev.netdev = dev; -+ priv->uap_dev.card = card; -+ priv->MediaConnected = FALSE; -+ uappriv = priv; -+ ((struct sdio_mmc_card *) card)->priv = priv; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) -+ SET_MODULE_OWNER(dev); -+#endif -+ -+ /* Setup the OS Interface to our functions */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) -+ dev->open = uap_open; -+ dev->stop = uap_close; -+ dev->hard_start_xmit = uap_hard_start_xmit; -+ dev->tx_timeout = uap_tx_timeout; -+ dev->get_stats = uap_get_stats; -+ dev->do_ioctl = uap_do_ioctl; -+ dev->set_mac_address = uap_set_mac_address; -+ dev->set_multicast_list = uap_set_multicast_list; -+#else -+ dev->netdev_ops = &uap_netdev_ops; -+#endif -+ dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT; -+ dev->hard_header_len += sizeof(TxPD) + INTF_HEADER_LEN; -+ dev->hard_header_len += HEADER_ALIGNMENT; -+#define NETIF_F_DYNALLOC 16 -+ dev->features |= NETIF_F_DYNALLOC; -+ dev->flags |= IFF_BROADCAST | IFF_MULTICAST; -+ -+ /* Init SW */ -+ if (uap_init_sw(priv)) { -+ PRINTM(FATAL, "Software Init Failed\n"); -+ goto error; -+ } -+ -+ PRINTM(INFO, "Starting kthread...\n"); -+ priv->MainThread.priv = priv; -+ spin_lock_init(&priv->driver_lock); -+ uap_create_thread(uap_service_main_thread, &priv->MainThread, -+ "uap_main_service"); -+ while (priv->MainThread.pid == 0) { -+ os_sched_timeout(2); -+ } -+ -+ /* Register the device */ -+ if (sbi_register_dev(priv) < 0) { -+ PRINTM(FATAL, "Failed to register uap device!\n"); -+ goto err_registerdev; -+ } -+#ifdef FW_DNLD_NEEDED -+ SET_NETDEV_DEV(dev, priv->hotplug_device); -+#endif -+ -+ /* Init FW and HW */ -+ if (uap_init_fw(priv)) { -+ PRINTM(FATAL, "Firmware Init Failed\n"); -+ goto err_init_fw; -+ } -+ -+ priv->uap_dev.cmd_sent = FALSE; -+ priv->uap_dev.data_sent = FALSE; -+ -+ /* Get mac address from firmware */ -+ if (uap_get_mac_address(priv)) { -+ PRINTM(FATAL, "Fail to get mac address\n"); -+ goto err_init_fw; -+ } -+ /* Register network device */ -+ if (register_netdev(dev)) { -+ printk(KERN_ERR "Cannot register network device!\n"); -+ goto err_init_fw; -+ } -+#ifdef CONFIG_PROC_FS -+ uap_proc_entry(priv, dev); -+ uap_debug_entry(priv, dev); -+#endif /* CPNFIG_PROC_FS */ -+ OS_REL_SEMAPHORE(&AddRemoveCardSem); -+ -+ LEAVE(); -+ return priv; -+ err_init_fw: -+ sbi_unregister_dev(priv); -+ err_registerdev: -+ ((struct sdio_mmc_card *) card)->priv = NULL; -+ /* Stop the thread servicing the interrupts */ -+ priv->adapter->SurpriseRemoved = TRUE; -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ while (priv->MainThread.pid) { -+ os_sched_timeout(1); -+ } -+ error: -+ if (dev) { -+ if (dev->reg_state == NETREG_REGISTERED) -+ unregister_netdev(dev); -+ if (priv->adapter) -+ uap_free_adapter(priv); -+ free_netdev(dev); -+ uappriv = NULL; -+ } -+ OS_REL_SEMAPHORE(&AddRemoveCardSem); -+ exit_sem_err: -+ LEAVE(); -+ return NULL; -+} -+ -+/** -+ * @brief This function removes the card. -+ * -+ * @param card A pointer to card -+ * @return UAP_STATUS_SUCCESS -+ */ -+int -+uap_remove_card(void *card) -+{ -+ uap_private *priv = uappriv; -+ uap_adapter *Adapter; -+ struct net_device *dev; -+ -+ ENTER(); -+ -+ if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) -+ goto exit_sem_err; -+ -+ if (!priv || !(Adapter = priv->adapter)) { -+ goto exit_remove; -+ } -+ Adapter->SurpriseRemoved = TRUE; -+ if (Adapter->cmd_pending == TRUE) { -+ /* Wake up cmd Q */ -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ } -+ dev = priv->uap_dev.netdev; -+ if (priv->MediaConnected == TRUE) { -+ os_stop_queue(priv); -+ os_carrier_off(priv); -+ priv->MediaConnected = FALSE; -+ } -+ Adapter->CmdSize = 0; -+ Adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&Adapter->cmdwait_q); -+ skb_queue_purge(&priv->adapter->tx_queue); -+ skb_queue_purge(&priv->adapter->cmd_queue); -+ -+ /* Disable interrupts on the card */ -+ sbi_disable_host_int(priv); -+ PRINTM(INFO, "netdev_finish_unregister: %s%s.\n", dev->name, -+ (dev->features & NETIF_F_DYNALLOC) ? "" : ", old style"); -+ unregister_netdev(dev); -+ PRINTM(INFO, "Unregister finish\n"); -+ wake_up_interruptible(&priv->MainThread.waitQ); -+ while (priv->MainThread.pid) { -+ os_sched_timeout(1); -+ } -+ -+ if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) { -+ sock_release((Adapter->nl_sk)->sk_socket); -+ Adapter->nl_sk = NULL; -+ } -+#ifdef CONFIG_PROC_FS -+ uap_debug_remove(priv); -+ uap_proc_remove(priv); -+#endif -+ sbi_unregister_dev(priv); -+ PRINTM(INFO, "Free Adapter\n"); -+ uap_free_adapter(priv); -+ priv->uap_dev.netdev = NULL; -+ free_netdev(dev); -+ uappriv = NULL; -+ -+ exit_remove: -+ OS_REL_SEMAPHORE(&AddRemoveCardSem); -+ exit_sem_err: -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function initializes module. -+ * -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int __init -+uap_init_module(void) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ ENTER(); -+ -+ OS_INIT_SEMAPHORE(&AddRemoveCardSem); -+ ret = sbi_register(); -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function cleans module -+ * -+ * @return n/a -+ */ -+static void __exit -+uap_cleanup_module(void) -+{ -+ ENTER(); -+ -+ if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem)) -+ goto exit_sem_err; -+ -+ if ((uappriv) && (uappriv->adapter)) { -+ uap_func_shutdown(uappriv); -+ } -+ OS_REL_SEMAPHORE(&AddRemoveCardSem); -+ exit_sem_err: -+ sbi_unregister(); -+ LEAVE(); -+} -+ -+module_init(uap_init_module); -+module_exit(uap_cleanup_module); -+module_param(helper_name, charp, 0); -+MODULE_PARM_DESC(helper_name, "Helper name"); -+module_param(fw_name, charp, 0); -+MODULE_PARM_DESC(fw_name, "Firmware name"); -+ -+MODULE_DESCRIPTION("M-UAP Driver"); -+MODULE_AUTHOR("Marvell International Ltd."); -+MODULE_VERSION(DRIVER_VERSION); -+MODULE_LICENSE("GPL"); -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_proc.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_proc.c ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_proc.c 1970-01-01 01:00:00.000000000 +0100 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_proc.c 2012-07-31 14:23:04.000000000 +0200 -@@ -0,0 +1,296 @@ -+/** @file uap_proc.c -+ * @brief This file contains functions for proc file. -+ * -+ * Copyright (C) 2008-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+#ifdef CONFIG_PROC_FS -+#include "uap_headers.h" -+ -+/** /proc directory root */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -+#define PROC_DIR NULL -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+#define PROC_DIR &proc_root -+#else -+#define PROC_DIR proc_net -+#endif -+ -+/******************************************************** -+ Local Variables -+********************************************************/ -+ -+/******************************************************** -+ Global Variables -+********************************************************/ -+ -+/******************************************************** -+ Local Functions -+********************************************************/ -+ -+/** -+ * @brief proc read function -+ * -+ * @param page pointer to buffer -+ * @param start read data starting position -+ * @param offset offset -+ * @param count counter -+ * @param eof end of file flag -+ * @param data data to output -+ * @return number of output data -+ */ -+static int -+uap_proc_read(char *page, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ int i; -+ char *p = page; -+ struct net_device *netdev = data; -+ struct netdev_hw_addr *ha; -+ char fmt[64]; -+ uap_private *priv = (uap_private *) netdev_priv(netdev); -+ -+ if (offset != 0) { -+ *eof = 1; -+ goto exit; -+ } -+ -+ strcpy(fmt, DRIVER_VERSION); -+ -+ p += sprintf(p, "driver_name = " ""uap"\n"); -+ p += sprintf(p, "driver_version = %s-(FP%s)", fmt, FPNUM); -+ p += sprintf(p, "\nInterfaceName="%s"\n", netdev->name); -+ p += sprintf(p, "State="%s"\n", -+ ((priv->MediaConnected == -+ FALSE) ? "Disconnected" : "Connected")); -+ p += sprintf(p, "MACAddress="%02x:%02x:%02x:%02x:%02x:%02x"\n", -+ netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], -+ netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); -+ i = 0; -+ netdev_for_each_mc_addr(ha, netdev) { -+ ++i; -+ } -+ p += sprintf(p, "MCCount="%d"\n", i); -+ -+ /* -+ * Put out the multicast list -+ */ -+ i = 0; -+ netdev_for_each_mc_addr(ha, netdev) { -+ p += sprintf(p, -+ "MCAddr[%d]="%02x:%02x:%02x:%02x:%02x:%02x"\n", -+ i++, -+ ha->addr[0], ha->addr[1], -+ ha->addr[2], ha->addr[3], -+ ha->addr[4], ha->addr[5]); -+ } -+ -+ p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes); -+ p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes); -+ p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets); -+ p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets); -+ p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped); -+ p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped); -+ p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors); -+ p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); -+ p += sprintf(p, "num_tx_timeout = %u\n", priv->num_tx_timeout); -+ p += sprintf(p, "carrier %s\n", -+ ((netif_carrier_ok(priv->uap_dev.netdev)) ? "on" : "off")); -+ p += sprintf(p, "tx queue %s\n", -+ ((netif_queue_stopped(priv->uap_dev.netdev)) ? "stopped" : -+ "started")); -+ -+ exit: -+ return (p - page); -+} -+ -+/** -+ * @brief hwstatus proc write function -+ * -+ * @param f file pointer -+ * @param buf pointer to data buffer -+ * @param cnt data number to write -+ * @param data data to write -+ * @return number of data -+ */ -+static int -+uap_hwstatus_write(struct file *f, const char *buf, unsigned long cnt, -+ void *data) -+{ -+ struct net_device *netdev = data; -+ uap_private *priv = (uap_private *) netdev_priv(netdev); -+ char databuf[10]; -+ int hwstatus; -+ MODULE_GET; -+ if (cnt > 10) { -+ MODULE_PUT; -+ return cnt; -+ } -+ if (copy_from_user(databuf, buf, cnt)) { -+ MODULE_PUT; -+ return 0; -+ } -+ hwstatus = string_to_number(databuf); -+ switch (hwstatus) { -+ case HWReset: -+ PRINTM(MSG, "reset hw\n"); -+ uap_soft_reset(priv); -+ priv->adapter->HardwareStatus = HWReset; -+ break; -+ default: -+ break; -+ } -+ MODULE_PUT; -+ return cnt; -+} -+ -+/** -+ * @brief hwstatus proc read function -+ * -+ * @param page pointer to buffer -+ * @param s read data starting position -+ * @param off offset -+ * @param cnt counter -+ * @param eof end of file flag -+ * @param data data to output -+ * @return number of output data -+ */ -+static int -+uap_hwstatus_read(char *page, char **s, off_t off, int cnt, int *eof, -+ void *data) -+{ -+ char *p = page; -+ struct net_device *netdev = data; -+ uap_private *priv = (uap_private *) netdev_priv(netdev); -+ MODULE_GET; -+ p += sprintf(p, "%d\n", priv->adapter->HardwareStatus); -+ MODULE_PUT; -+ return p - page; -+} -+ -+/******************************************************** -+ Global Functions -+********************************************************/ -+/** -+ * @brief create uap proc file -+ * -+ * @param priv pointer uap_private -+ * @param dev pointer net_device -+ * @return N/A -+ */ -+void -+uap_proc_entry(uap_private * priv, struct net_device *dev) -+{ -+ struct proc_dir_entry *r = PROC_DIR; -+ -+ PRINTM(INFO, "Creating Proc Interface\n"); -+ /* Check if uap directory already exists */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) -+ for (r = r->subdir; r; r = r->next) { -+ if (r->namelen && !strcmp("uap", r->name)) { -+ /* Directory exists */ -+ PRINTM(WARN, "proc directory already exists!\n"); -+ priv->proc_uap = r; -+ break; -+ } -+ } -+#endif -+ if (!priv->proc_uap) { -+ priv->proc_uap = proc_mkdir("uap", PROC_DIR); -+ if (!priv->proc_uap) -+ return; -+ else -+ atomic_set(&priv->proc_uap->count, 1); -+ } else { -+ atomic_inc(&priv->proc_uap->count); -+ } -+ priv->proc_entry = proc_mkdir(dev->name, priv->proc_uap); -+ -+ if (priv->proc_entry) { -+ r = create_proc_read_entry("info", 0, priv->proc_entry, uap_proc_read, -+ dev); -+ r = create_proc_entry("hwstatus", 0644, priv->proc_entry); -+ if (r) { -+ r->data = dev; -+ r->read_proc = uap_hwstatus_read; -+ r->write_proc = uap_hwstatus_write; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) -+ r->owner = THIS_MODULE; -+#endif -+ } else -+ PRINTM(MSG, "Fail to create proc hwstatus\n"); -+ } -+} -+ -+/** -+ * @brief remove proc file -+ * -+ * @param priv pointer uap_private -+ * @return N/A -+ */ -+void -+uap_proc_remove(uap_private * priv) -+{ -+ if (priv->proc_uap) { -+ if (priv->proc_entry) { -+ remove_proc_entry("info", priv->proc_entry); -+ remove_proc_entry("hwstatus", priv->proc_entry); -+ } -+ remove_proc_entry(priv->uap_dev.netdev->name, priv->proc_uap); -+ atomic_dec(&priv->proc_uap->count); -+ if (atomic_read(&(priv->proc_uap->count)) == 0) -+ remove_proc_entry("uap", PROC_DIR); -+ } -+} -+ -+/** -+ * @brief convert string to number -+ * -+ * @param s pointer to numbered string -+ * @return converted number from string s -+ */ -+int -+string_to_number(char *s) -+{ -+ int r = 0; -+ int base = 0; -+ int pn = 1; -+ -+ if (strncmp(s, "-", 1) == 0) { -+ pn = -1; -+ s++; -+ } -+ if ((strncmp(s, "0x", 2) == 0) || (strncmp(s, "0X", 2) == 0)) { -+ base = 16; -+ s += 2; -+ } else -+ base = 10; -+ -+ for (s = s; *s != 0; s++) { -+ if ((*s >= '0') && (*s <= '9')) -+ r = (r * base) + (*s - '0'); -+ else if ((*s >= 'A') && (*s <= 'F')) -+ r = (r * base) + (*s - 'A' + 10); -+ else if ((*s >= 'a') && (*s <= 'f')) -+ r = (r * base) + (*s - 'a' + 10); -+ else -+ break; -+ } -+ -+ return (r * pn); -+} -+ -+#endif -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c 1970-01-01 01:00:00.000000000 +0100 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c 2012-07-31 14:23:04.000000000 +0200 -@@ -0,0 +1,1428 @@ -+/** @file uap_sdio_mmc.c -+ * @brief This file contains SDIO IF (interface) module -+ * related functions. -+ * -+ * Copyright (C) 2007-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+/**************************************************** -+Change log: -+****************************************************/ -+ -+#include "uap_sdio_mmc.h" -+ -+#include <linux/firmware.h> -+ -+/** define SDIO block size */ -+/* We support up to 480-byte block size due to FW buffer limitation. */ -+#define SD_BLOCK_SIZE 256 -+ -+/** define allocated buffer size */ -+#define ALLOC_BUF_SIZE (((MAX(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, \ -+ MRVDRV_SIZE_OF_CMD_BUFFER) + INTF_HEADER_LEN \ -+ + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE) * SD_BLOCK_SIZE) -+ -+/** Max retry number of CMD53 write */ -+#define MAX_WRITE_IOMEM_RETRY 2 -+ -+/******************************************************** -+ Local Variables -+********************************************************/ -+ -+/** SDIO Rx unit */ -+static u8 sdio_rx_unit = 0; -+ -+/**Interrupt status */ -+static u8 sd_ireg = 0; -+/******************************************************** -+ Global Variables -+********************************************************/ -+extern u8 *helper_name; -+extern u8 *fw_name; -+/** Default helper name */ -+#define DEFAULT_HELPER_NAME "mrvl/helper_sd.bin" -+/** Default firmware name */ -+#define DEFAULT_FW_NAME "mrvl/sd8688_ap.bin" -+ -+/******************************************************** -+ Local Functions -+********************************************************/ -+/** -+ * @brief This function reads the IO register. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param reg register to be read -+ * @param dat A pointer to variable that keeps returned value -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sbi_read_ioreg(uap_private * priv, u32 reg, u8 * dat) -+{ -+ struct sdio_mmc_card *card; -+ int ret = UAP_STATUS_FAILURE; -+ -+ ENTER(); -+ -+ card = priv->uap_dev.card; -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_read_ioreg(): card or function is NULL!\n"); -+ goto done; -+ } -+ -+ *dat = sdio_readb(card->func, reg, &ret); -+ if (ret) { -+ PRINTM(ERROR, "sbi_read_ioreg(): sdio_readb failed! ret=%d\n", ret); -+ goto done; -+ } -+ -+ PRINTM(INFO, "sbi_read_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv, -+ card->func->num, reg, *dat); -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function writes the IO register. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param reg register to be written -+ * @param dat the value to be written -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sbi_write_ioreg(uap_private * priv, u32 reg, u8 dat) -+{ -+ struct sdio_mmc_card *card; -+ int ret = UAP_STATUS_FAILURE; -+ -+ ENTER(); -+ -+ card = priv->uap_dev.card; -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_write_ioreg(): card or function is NULL!\n"); -+ goto done; -+ } -+ -+ PRINTM(INFO, "sbi_write_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv, -+ card->func->num, reg, dat); -+ -+ sdio_writeb(card->func, dat, reg, &ret); -+ if (ret) { -+ PRINTM(ERROR, "sbi_write_ioreg(): sdio_readb failed! ret=%d\n", ret); -+ goto done; -+ } -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function get rx_unit value -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sd_get_rx_unit(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 reg; -+ -+ ENTER(); -+ -+ ret = sbi_read_ioreg(priv, CARD_RX_UNIT_REG, ®); -+ if (ret == UAP_STATUS_SUCCESS) -+ sdio_rx_unit = reg; -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function reads rx length -+ * -+ * @param priv A pointer to uap_private structure -+ * @param dat A pointer to keep returned data -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sd_read_rx_len(uap_private * priv, u16 * dat) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 reg; -+ -+ ENTER(); -+ -+ ret = sbi_read_ioreg(priv, CARD_RX_LEN_REG, ®); -+ if (ret == UAP_STATUS_SUCCESS) -+ *dat = (u16) reg << sdio_rx_unit; -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function reads fw status registers -+ * -+ * @param priv A pointer to uap_private structure -+ * @param dat A pointer to keep returned data -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sd_read_firmware_status(uap_private * priv, u16 * dat) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 fws0; -+ u8 fws1; -+ -+ ENTER(); -+ -+ ret = sbi_read_ioreg(priv, CARD_FW_STATUS0_REG, &fws0); -+ if (ret < 0) { -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ ret = sbi_read_ioreg(priv, CARD_FW_STATUS1_REG, &fws1); -+ if (ret < 0) { -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ *dat = (((u16) fws1) << 8) | fws0; -+ -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function polls the card status register. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param bits the bit mask -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+mv_sdio_poll_card_status(uap_private * priv, u8 bits) -+{ -+ int tries; -+ u8 cs; -+ -+ ENTER(); -+ -+ for (tries = 0; tries < MAX_POLL_TRIES; tries++) { -+ if (sbi_read_ioreg(priv, CARD_STATUS_REG, &cs) < 0) -+ break; -+ else if ((cs & bits) == bits) { -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+ } -+ udelay(10); -+ } -+ -+ PRINTM(WARN, "mv_sdio_poll_card_status failed, tries = %d\n", tries); -+ -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+} -+ -+/** -+ * @brief This function set the sdio bus width. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param mode 1--1 bit mode, 4--4 bit mode -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+#if 0 -+static int -+sdio_set_bus_width(uap_private * priv, u8 mode) -+{ -+ ENTER(); -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+#endif -+ -+/** -+ * @brief This function reads data from the card. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+sd_card_to_host(uap_private * priv) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u16 buf_len = 0; -+ int buf_block_len; -+ int blksz; -+ struct sk_buff *skb = NULL; -+ u16 type; -+ u8 *payload = NULL; -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "card or function is NULL!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto exit; -+ } -+ -+ /* Read the length of data to be transferred */ -+ ret = sd_read_rx_len(priv, &buf_len); -+ if (ret < 0) { -+ PRINTM(ERROR, "card_to_host, read scratch reg failed\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto exit; -+ } -+ -+ /* Allocate buffer */ -+ blksz = SD_BLOCK_SIZE; -+ buf_block_len = (buf_len + blksz - 1) / blksz; -+ if (buf_len <= INTF_HEADER_LEN || (buf_block_len * blksz) > ALLOC_BUF_SIZE) { -+ PRINTM(ERROR, "card_to_host, invalid packet length: %d\n", buf_len); -+ ret = UAP_STATUS_FAILURE; -+ goto exit; -+ } -+#ifdef PXA3XX_DMA_ALIGN -+ skb = dev_alloc_skb(buf_block_len * blksz + PXA3XX_DMA_ALIGNMENT); -+#else -+ skb = dev_alloc_skb(buf_block_len * blksz); -+#endif -+ if (skb == NULL) { -+ PRINTM(WARN, "No free skb\n"); -+ goto exit; -+ } -+#ifdef PXA3XX_DMA_ALIGN -+ if ((u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)) { -+ skb_put(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)); -+ skb_pull(skb, (u32) skb->data & (PXA3XX_DMA_ALIGNMENT - 1)); -+ } -+#endif /* PXA3XX_DMA_ALIGN */ -+ -+ payload = skb->tail; -+ ret = sdio_readsb(card->func, payload, priv->uap_dev.ioport, -+ buf_block_len * blksz); -+ if (ret < 0) { -+ PRINTM(ERROR, "card_to_host, read iomem failed: %d\n", ret); -+ ret = UAP_STATUS_FAILURE; -+ goto exit; -+ } -+ HEXDUMP("SDIO Blk Rd", payload, blksz * buf_block_len); -+ /* -+ * This is SDIO specific header -+ * u16 length, -+ * u16 type (MV_TYPE_DAT = 0, MV_TYPE_CMD = 1, MV_TYPE_EVENT = 3) -+ */ -+ buf_len = uap_le16_to_cpu(*(u16 *) & payload[0]); -+ type = uap_le16_to_cpu(*(u16 *) & payload[2]); -+ switch (type) { -+ case MV_TYPE_EVENT: -+ skb_put(skb, buf_len); -+ skb_pull(skb, INTF_HEADER_LEN); -+ uap_process_event(priv, skb->data, skb->len); -+ kfree_skb(skb); -+ skb = NULL; -+ break; -+ case MV_TYPE_CMD: -+ skb_put(skb, buf_len); -+ skb_pull(skb, INTF_HEADER_LEN); -+ priv->adapter->cmd_pending = FALSE; -+ if (priv->adapter->cmd_wait_option == -+ HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM) { -+ priv->adapter->cmd_wait_option = FALSE; -+ uap_process_sleep_confirm_resp(priv, skb->data, skb->len); -+ } else if (priv->adapter->cmd_wait_option) { -+ memcpy(priv->adapter->CmdBuf, skb->data, skb->len); -+ priv->adapter->CmdSize = skb->len; -+ priv->adapter->cmd_wait_option = FALSE; -+ priv->adapter->CmdWaitQWoken = TRUE; -+ wake_up_interruptible(&priv->adapter->cmdwait_q); -+ } -+ kfree_skb(skb); -+ skb = NULL; -+ break; -+ case MV_TYPE_DAT: -+ skb_put(skb, buf_len); -+ skb_pull(skb, INTF_HEADER_LEN); -+ uap_process_rx_packet(priv, skb); -+ break; -+ default: -+ priv->stats.rx_errors++; -+ priv->stats.rx_dropped++; -+ /* Driver specified event and command resp should be handle here */ -+ PRINTM(INFO, "Unknown PKT type:%d\n", type); -+ kfree_skb(skb); -+ skb = NULL; -+ break; -+ } -+ exit: -+ if (ret) { -+ if (skb) -+ kfree_skb(skb); -+ } -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function enables the host interrupts mask -+ * -+ * @param priv A pointer to uap_private structure -+ * @param mask the interrupt mask -+ * @return UAP_STATUS_SUCCESS -+ */ -+static int -+enable_host_int_mask(uap_private * priv, u8 mask) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ /* Simply write the mask to the register */ -+ ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, mask); -+ -+ if (ret) { -+ PRINTM(WARN, "Unable to enable the host interrupt!\n"); -+ ret = UAP_STATUS_FAILURE; -+ } -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** @brief This function disables the host interrupts mask. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param mask the interrupt mask -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+disable_host_int_mask(uap_private * priv, u8 mask) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 host_int_mask; -+ -+ ENTER(); -+ -+ /* Read back the host_int_mask register */ -+ ret = sbi_read_ioreg(priv, HOST_INT_MASK_REG, &host_int_mask); -+ if (ret) { -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ -+ /* Update with the mask and write back to the register */ -+ host_int_mask &= ~mask; -+ ret = sbi_write_ioreg(priv, HOST_INT_MASK_REG, host_int_mask); -+ if (ret < 0) { -+ PRINTM(WARN, "Unable to diable the host interrupt!\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/******************************************************** -+ Global Functions -+********************************************************/ -+ -+/** -+ * @brief This function handles the interrupt. -+ * -+ * @param func A pointer to sdio_func structure. -+ * @return n/a -+ */ -+static void -+sbi_interrupt(struct sdio_func *func) -+{ -+ struct sdio_mmc_card *card; -+ uap_private *priv; -+ u8 ireg = 0; -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ card = sdio_get_drvdata(func); -+ if (!card || !card->priv) { -+ PRINTM(MSG, "%s: sbi_interrupt(%p) card or priv is NULL, card=%p\n", -+ __FUNCTION__, func, card); -+ LEAVE(); -+ return; -+ } -+ priv = card->priv; -+#ifdef FW_WAKEUP_TIME -+ if ((priv->adapter->wt_pwrup_sending != 0L) && -+ (priv->adapter->wt_int == 0L)) -+ priv->adapter->wt_int = get_utimeofday(); -+#endif -+ -+ ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret); -+ if (ret) { -+ PRINTM(WARN, "sdio_read_ioreg: read int status register failed\n"); -+ goto done; -+ } -+ if (ireg != 0) { -+ /* -+ * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS -+ * Clear the interrupt status register and re-enable the interrupt -+ */ -+ PRINTM(INFO, "sdio_ireg = 0x%x\n", ireg); -+ sdio_writeb(card->func, -+ ~(ireg) & (DN_LD_HOST_INT_STATUS | UP_LD_HOST_INT_STATUS), -+ HOST_INTSTATUS_REG, &ret); -+ if (ret) { -+ PRINTM(WARN, -+ "sdio_write_ioreg: clear int status register failed\n"); -+ goto done; -+ } -+ } -+ OS_INT_DISABLE; -+ sd_ireg |= ireg; -+ OS_INT_RESTORE; -+ -+ uap_interrupt(priv); -+ done: -+ LEAVE(); -+} -+ -+/** -+ * @brief This function probe the card -+ * -+ * @param func A pointer to sdio_func structure -+ * @param id A pointer to structure sd_device_id -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+static int -+uap_probe(struct sdio_func *func, const struct sdio_device_id *id) -+{ -+ int ret = UAP_STATUS_FAILURE; -+ struct sdio_mmc_card *card = NULL; -+ -+ ENTER(); -+ -+ PRINTM(MSG, "%s: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", -+ __FUNCTION__, func->vendor, func->device, func->class, func->num); -+ -+ card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); -+ if (!card) { -+ ret = -ENOMEM; -+ goto done; -+ } -+ -+ card->func = func; -+ -+ if (!uap_add_card(card)) { -+ PRINTM(ERROR, "%s: uap_add_callback failed\n", __FUNCTION__); -+ kfree(card); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ -+ ret = UAP_STATUS_SUCCESS; -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function removes the card -+ * -+ * @param func A pointer to sdio_func structure -+ * @return N/A -+ */ -+static void -+uap_remove(struct sdio_func *func) -+{ -+ struct sdio_mmc_card *card; -+ -+ ENTER(); -+ -+ if (func) { -+ card = sdio_get_drvdata(func); -+ if (card) { -+ uap_remove_card(card); -+ kfree(card); -+ } -+ } -+ -+ LEAVE(); -+} -+ -+#ifdef CONFIG_PM -+/** -+ * @brief This function handles client driver suspend -+ * -+ * @param func A pointer to sdio_func structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+uap_suspend(struct sdio_func *func) -+{ -+ ENTER(); -+ LEAVE(); -+ return 0; -+} -+ -+/** -+ * @brief This function handles client driver resume -+ * -+ * @param func A pointer to sdio_func structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+uap_resume(struct sdio_func *func) -+{ -+ ENTER(); -+ LEAVE(); -+ return 0; -+} -+#endif -+ -+/** Device ID for SD8688 */ -+#define SD_DEVICE_ID_8688_UAP 0x9104 -+/** UAP IDs */ -+static const struct sdio_device_id uap_ids[] = { -+ {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SD_DEVICE_ID_8688_UAP)}, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(sdio, uap_ids); -+ -+static struct sdio_driver uap_sdio = { -+ .name = "uap_sdio", -+ .id_table = uap_ids, -+ .probe = uap_probe, -+ .remove = uap_remove, -+#ifdef CONFIG_PM -+/* .suspend = uap_suspend, */ -+/* .resume = uap_resume, */ -+#endif -+ -+}; -+ -+/** -+ * @brief This function registers the IF module in bus driver. -+ * -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int __init -+sbi_register() -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ /* SDIO Driver Registration */ -+ if (sdio_register_driver(&uap_sdio) != 0) { -+ PRINTM(FATAL, "SDIO Driver Registration Failed \n"); -+ ret = UAP_STATUS_FAILURE; -+ } -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function de-registers the IF module in bus driver. -+ * -+ * @return n/a -+ */ -+void __exit -+sbi_unregister(void) -+{ -+ ENTER(); -+ -+ /* SDIO Driver Unregistration */ -+ sdio_unregister_driver(&uap_sdio); -+ -+ LEAVE(); -+} -+ -+/** -+ * @brief This function checks the interrupt status and handle it accordingly. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param ireg A pointer to variable that keeps returned value -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_get_int_status(uap_private * priv, u8 * ireg) -+{ -+ int ret = UAP_STATUS_SUCCESS; -+ u8 sdio_ireg = 0; -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ -+ ENTER(); -+ -+ *ireg = 0; -+ OS_INT_DISABLE; -+ sdio_ireg = sd_ireg; -+ sd_ireg = 0; -+ OS_INT_RESTORE; -+ -+ sdio_claim_host(card->func); -+ -+ if (sdio_ireg & DN_LD_HOST_INT_STATUS) { /* tx_done INT */ -+ if (!priv->uap_dev.cmd_sent) { /* tx_done already received */ -+ PRINTM(INFO, -+ "warning: tx_done already received: tx_dnld_rdy=0x%x int status=0x%x\n", -+ priv->uap_dev.cmd_sent, sdio_ireg); -+ } else { -+ priv->uap_dev.cmd_sent = FALSE; -+ priv->uap_dev.data_sent = FALSE; -+ if ( (priv->uap_dev.netdev->reg_state == NETREG_REGISTERED) && (skb_queue_len(&priv->adapter->tx_queue) < TX_LOW_WATERMARK)) { -+ os_start_queue(priv); -+ } -+ } -+ } -+ if (sdio_ireg & UP_LD_HOST_INT_STATUS) { -+ sd_card_to_host(priv); -+ } -+ -+ *ireg = sdio_ireg; -+ ret = UAP_STATUS_SUCCESS; -+ sdio_release_host(card->func); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function disables the host interrupts. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_disable_host_int(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret; -+ -+ ENTER(); -+ -+ sdio_claim_host(card->func); -+ ret = disable_host_int_mask(priv, HIM_DISABLE); -+ sdio_release_host(card->func); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function enables the host interrupts. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS -+ */ -+int -+sbi_enable_host_int(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret; -+ -+ ENTER(); -+ -+ sdio_claim_host(card->func); -+ ret = enable_host_int_mask(priv, HIM_ENABLE); -+ sdio_release_host(card->func); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function de-registers the device. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS -+ */ -+int -+sbi_unregister_dev(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "Error: card or function is NULL!\n"); -+ goto done; -+ } -+ -+ sdio_claim_host(card->func); -+ sdio_release_irq(card->func); -+ sdio_disable_func(card->func); -+ sdio_release_host(card->func); -+ -+ sdio_set_drvdata(card->func, NULL); -+ -+ done: -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+ -+/** -+ * @brief This function registers the device. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_register_dev(uap_private * priv) -+{ -+ int ret = UAP_STATUS_FAILURE; -+ u8 reg; -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ struct sdio_func *func; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "Error: card or function is NULL!\n"); -+ goto done; -+ } -+ -+ func = card->func; -+ -+ /* Initialize the private structure */ -+ priv->uap_dev.ioport = 0; -+ -+ sdio_claim_host(func); -+ -+ ret = sdio_enable_func(func); -+ if (ret) { -+ PRINTM(FATAL, "sdio_enable_func() failed: ret=%d\n", ret); -+ goto release_host; -+ } -+ -+ ret = sdio_claim_irq(func, sbi_interrupt); -+ if (ret) { -+ PRINTM(FATAL, "sdio_claim_irq failed: ret=%d\n", ret); -+ goto disable_func; -+ } -+ -+ /* Read the IO port */ -+ ret = sbi_read_ioreg(priv, IO_PORT_0_REG, ®); -+ if (ret) -+ goto release_irq; -+ else -+ priv->uap_dev.ioport |= reg; -+ -+ ret = sbi_read_ioreg(priv, IO_PORT_1_REG, ®); -+ if (ret) -+ goto release_irq; -+ else -+ priv->uap_dev.ioport |= (reg << 8); -+ -+ ret = sbi_read_ioreg(priv, IO_PORT_2_REG, ®); -+ if (ret) -+ goto release_irq; -+ else -+ priv->uap_dev.ioport |= (reg << 16); -+ -+ PRINTM(INFO, "SDIO FUNC #%d IO port: 0x%x\n", func->num, -+ priv->uap_dev.ioport); -+ -+ ret = sdio_set_block_size(card->func, SD_BLOCK_SIZE); -+ if (ret) { -+ PRINTM(ERROR, "%s: cannot set SDIO block size\n", __FUNCTION__); -+ ret = UAP_STATUS_FAILURE; -+ goto release_irq; -+ } -+ priv->hotplug_device = &func->dev; -+ -+ if (helper_name == NULL) { -+ helper_name = DEFAULT_HELPER_NAME; -+ } -+ if (fw_name == NULL) { -+ fw_name = DEFAULT_FW_NAME; -+ } -+ sdio_release_host(func); -+ -+ sdio_set_drvdata(func, card); -+ -+ ret = UAP_STATUS_SUCCESS; -+ goto done; -+ -+ release_irq: -+ sdio_release_irq(func); -+ disable_func: -+ sdio_disable_func(func); -+ release_host: -+ sdio_release_host(func); -+ -+ done: -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function sends data to the card. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param payload A pointer to the data/cmd buffer -+ * @param nb the length of data/cmd -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret = UAP_STATUS_SUCCESS; -+ int buf_block_len; -+ int blksz; -+ int i = 0; -+ u8 *buf = NULL; -+#ifdef PXA3XX_DMA_ALIGN -+ void *tmpbuf = NULL; -+ int tmpbufsz; -+#endif -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "card or function is NULL!\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ buf = payload; -+#ifdef PXA3XX_DMA_ALIGN -+ if ((u32) payload & (PXA3XX_DMA_ALIGNMENT - 1)) { -+ tmpbufsz = ALIGN_SZ(nb, PXA3XX_DMA_ALIGNMENT); -+ tmpbuf = kmalloc(tmpbufsz, GFP_KERNEL); -+ memset(tmpbuf, 0, tmpbufsz); -+ /* Ensure 8-byte aligned CMD buffer */ -+ buf = (u8 *) ALIGN_ADDR(tmpbuf, PXA3XX_DMA_ALIGNMENT); -+ memcpy(buf, payload, nb); -+ } -+#endif -+ /* Allocate buffer and copy payload */ -+ blksz = SD_BLOCK_SIZE; -+ buf_block_len = (nb + blksz - 1) / blksz; -+ sdio_claim_host(card->func); -+#define MAX_WRITE_IOMEM_RETRY 2 -+ priv->uap_dev.cmd_sent = TRUE; -+ priv->uap_dev.data_sent = TRUE; -+ do { -+ /* Transfer data to card */ -+ ret = sdio_writesb(card->func, priv->uap_dev.ioport, buf, -+ buf_block_len * blksz); -+ if (ret < 0) { -+ i++; -+ PRINTM(ERROR, "host_to_card, write iomem (%d) failed: %d\n", i, -+ ret); -+ ret = UAP_STATUS_FAILURE; -+ if (i > MAX_WRITE_IOMEM_RETRY) -+ goto exit; -+ } else { -+ HEXDUMP("SDIO Blk Wr", payload, nb); -+ } -+ } while (ret == UAP_STATUS_FAILURE); -+ exit: -+ sdio_release_host(card->func); -+#ifdef PXA3XX_DMA_ALIGN -+ if (tmpbuf) -+ kfree(tmpbuf); -+#endif -+ if (ret == UAP_STATUS_FAILURE) { -+ priv->uap_dev.cmd_sent = FALSE; -+ priv->uap_dev.data_sent = FALSE; -+ } -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function reads CIS information. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param cisinfo A pointer to CIS information output buffer -+ * @param cislen A pointer to length of CIS info output buffer -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+#if 0 -+static int -+sbi_get_cis_info(uap_private * priv, void *cisinfo, int *cislen) -+{ -+#define CIS_PTR (0x8000) -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ unsigned int i, cis_ptr = CIS_PTR; -+ int ret = UAP_STATUS_FAILURE; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_get_cis_info(): card or function is NULL!\n"); -+ goto exit; -+ } -+#define MAX_SDIO_CIS_INFO_LEN (256) -+ if (!cisinfo || (*cislen < MAX_SDIO_CIS_INFO_LEN)) { -+ PRINTM(WARN, "ERROR! get_cis_info: insufficient buffer passed\n"); -+ goto exit; -+ } -+ -+ *cislen = MAX_SDIO_CIS_INFO_LEN; -+ -+ sdio_claim_host(card->func); -+ -+ PRINTM(INFO, "cis_ptr=%#x\n", cis_ptr); -+ -+ /* Read the Tuple Data */ -+ for (i = 0; i < *cislen; i++) { -+ ((unsigned char *) cisinfo)[i] = -+ sdio_readb(card->func, cis_ptr + i, &ret); -+ if (ret) { -+ PRINTM(WARN, "get_cis_info error: ret=%d\n", ret); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ PRINTM(INFO, "cisinfo[%d]=%#x\n", i, ((unsigned char *) cisinfo)[i]); -+ } -+ -+ done: -+ sdio_release_host(card->func); -+ exit: -+ LEAVE(); -+ return ret; -+} -+#endif -+/** -+ * @brief This function downloads helper image to the card. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_prog_helper(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ u8 *helper = NULL; -+ int helperlen; -+ int ret = UAP_STATUS_SUCCESS; -+ void *tmphlprbuf = NULL; -+ int tmphlprbufsz; -+ u8 *hlprbuf; -+ int hlprblknow; -+ u32 tx_len; -+#ifdef FW_DOWNLOAD_SPEED -+ u32 tv1, tv2; -+#endif -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_prog_helper(): card or function is NULL!\n"); -+ goto done; -+ } -+ -+ if (priv->fw_helper) { -+ helper = (u8 *) priv->fw_helper->data; -+ helperlen = priv->fw_helper->size; -+ } else { -+ PRINTM(MSG, "No helper image found! Terminating download.\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ PRINTM(INFO, "Downloading helper image (%d bytes), block size %d bytes\n", -+ helperlen, SD_BLOCK_SIZE); -+ -+#ifdef FW_DOWNLOAD_SPEED -+ tv1 = get_utimeofday(); -+#endif -+ -+#ifdef PXA3XX_DMA_ALIGN -+ tmphlprbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT); -+#else /* !PXA3XX_DMA_ALIGN */ -+ tmphlprbufsz = UAP_UPLD_SIZE; -+#endif /* !PXA3XX_DMA_ALIGN */ -+ tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL); -+ if (!tmphlprbuf) { -+ PRINTM(ERROR, -+ "Unable to allocate buffer for helper. Terminating download\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ memset(tmphlprbuf, 0, tmphlprbufsz); -+#ifdef PXA3XX_DMA_ALIGN -+ hlprbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, PXA3XX_DMA_ALIGNMENT); -+#else /* !PXA3XX_DMA_ALIGN */ -+ hlprbuf = (u8 *) tmphlprbuf; -+#endif /* !PXA3XX_DMA_ALIGN */ -+ -+ sdio_claim_host(card->func); -+ -+ /* Perform helper data transfer */ -+ tx_len = (FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE) - INTF_HEADER_LEN; -+ hlprblknow = 0; -+ do { -+ /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */ -+ ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY); -+ if (ret < 0) { -+ PRINTM(FATAL, "Helper download poll status timeout @ %d\n", -+ hlprblknow); -+ goto done; -+ } -+ -+ /* More data? */ -+ if (hlprblknow >= helperlen) -+ break; -+ -+ /* Set blocksize to transfer - checking for last block */ -+ if (helperlen - hlprblknow < tx_len) -+ tx_len = helperlen - hlprblknow; -+ -+ /* Set length to the 4-byte header */ -+ *(u32 *) hlprbuf = uap_cpu_to_le32(tx_len); -+ -+ /* Copy payload to buffer */ -+ memcpy(&hlprbuf[INTF_HEADER_LEN], &helper[hlprblknow], tx_len); -+ -+ PRINTM(INFO, "."); -+ -+ /* Send data */ -+ ret = sdio_writesb(card->func, priv->uap_dev.ioport, -+ hlprbuf, FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE); -+ -+ if (ret < 0) { -+ PRINTM(FATAL, "IO error during helper download @ %d\n", hlprblknow); -+ goto done; -+ } -+ -+ hlprblknow += tx_len; -+ } while (TRUE); -+ -+#ifdef FW_DOWNLOAD_SPEED -+ tv2 = get_utimeofday(); -+ PRINTM(INFO, "helper: %ld.%03ld.%03ld ", tv1 / 1000000, -+ (tv1 % 1000000) / 1000, tv1 % 1000); -+ PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000, (tv2 % 1000000) / 1000, -+ tv2 % 1000); -+ tv2 -= tv1; -+ PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000, (tv2 % 1000000) / 1000, -+ tv2 % 1000); -+#endif -+ -+ /* Write last EOF data */ -+ PRINTM(INFO, "\nTransferring helper image EOF block\n"); -+ memset(hlprbuf, 0x0, SD_BLOCK_SIZE); -+ ret = sdio_writesb(card->func, priv->uap_dev.ioport, -+ hlprbuf, SD_BLOCK_SIZE); -+ -+ if (ret < 0) { -+ PRINTM(FATAL, "IO error in writing helper image EOF block\n"); -+ goto done; -+ } -+ -+ ret = UAP_STATUS_SUCCESS; -+ -+ done: -+ sdio_release_host(card->func); -+ if (tmphlprbuf) -+ kfree(tmphlprbuf); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function downloads firmware image to the card. -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_prog_fw_w_helper(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ u8 *firmware = NULL; -+ int firmwarelen; -+ u8 base0; -+ u8 base1; -+ int ret = UAP_STATUS_SUCCESS; -+ int offset; -+ void *tmpfwbuf = NULL; -+ int tmpfwbufsz; -+ u8 *fwbuf; -+ u16 len; -+ int txlen = 0; -+ int tx_blocks = 0; -+ int i = 0; -+ int tries = 0; -+#ifdef FW_DOWNLOAD_SPEED -+ u32 tv1, tv2; -+#endif -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "sbi_prog_fw_w_helper(): card or function is NULL!\n"); -+ goto done; -+ } -+ -+ if (priv->firmware) { -+ firmware = (u8 *) priv->firmware->data; -+ firmwarelen = priv->firmware->size; -+ } else { -+ PRINTM(MSG, "No firmware image found! Terminating download.\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ -+ PRINTM(INFO, "Downloading FW image (%d bytes)\n", firmwarelen); -+ -+#ifdef FW_DOWNLOAD_SPEED -+ tv1 = get_utimeofday(); -+#endif -+ -+#ifdef PXA3XX_DMA_ALIGN -+ tmpfwbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT); -+#else /* PXA3XX_DMA_ALIGN */ -+ tmpfwbufsz = UAP_UPLD_SIZE; -+#endif /* PXA3XX_DMA_ALIGN */ -+ tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL); -+ if (!tmpfwbuf) { -+ PRINTM(ERROR, -+ "Unable to allocate buffer for firmware. Terminating download.\n"); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ memset(tmpfwbuf, 0, tmpfwbufsz); -+#ifdef PXA3XX_DMA_ALIGN -+ /* Ensure 8-byte aligned firmware buffer */ -+ fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, PXA3XX_DMA_ALIGNMENT); -+#else /* PXA3XX_DMA_ALIGN */ -+ fwbuf = (u8 *) tmpfwbuf; -+#endif /* PXA3XX_DMA_ALIGN */ -+ -+ sdio_claim_host(card->func); -+ -+ /* Perform firmware data transfer */ -+ offset = 0; -+ do { -+ /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */ -+ ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY); -+ if (ret < 0) { -+ PRINTM(FATAL, "FW download with helper poll status timeout @ %d\n", -+ offset); -+ goto done; -+ } -+ -+ /* More data? */ -+ if (offset >= firmwarelen) -+ break; -+ -+ for (tries = 0; tries < MAX_POLL_TRIES; tries++) { -+ if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_0, &base0)) < 0) { -+ PRINTM(WARN, "Dev BASE0 register read failed:" -+ " base0=0x%04X(%d). Terminating download.\n", base0, -+ base0); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_1, &base1)) < 0) { -+ PRINTM(WARN, "Dev BASE1 register read failed:" -+ " base1=0x%04X(%d). Terminating download.\n", base1, -+ base1); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ len = (((u16) base1) << 8) | base0; -+ -+ /* For SD8688 wait until the length is not 0, 1 or 2 before -+ downloading the first FW block, since BOOT code writes the -+ register to indicate the helper/FW download winner, the value -+ could be 1 or 2 (Func1 or Func2). */ -+ if ((len && offset) || (len > 2)) -+ break; -+ udelay(10); -+ } -+ -+ if (len == 0) -+ break; -+ else if (len > UAP_UPLD_SIZE) { -+ PRINTM(FATAL, "FW download failure @ %d, invalid length %d\n", -+ offset, len); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ -+ txlen = len; -+ -+ if (len & BIT(0)) { -+ i++; -+ if (i > MAX_WRITE_IOMEM_RETRY) { -+ PRINTM(FATAL, -+ "FW download failure @ %d, over max retry count\n", -+ offset); -+ ret = UAP_STATUS_FAILURE; -+ goto done; -+ } -+ PRINTM(ERROR, "FW CRC error indicated by the helper:" -+ " len = 0x%04X, txlen = %d\n", len, txlen); -+ len &= ~BIT(0); -+ /* Setting this to 0 to resend from same offset */ -+ txlen = 0; -+ } else { -+ i = 0; -+ -+ /* Set blocksize to transfer - checking for last block */ -+ if (firmwarelen - offset < txlen) { -+ txlen = firmwarelen - offset; -+ } -+ PRINTM(INFO, "."); -+ -+ tx_blocks = (txlen + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE; -+ -+ /* Copy payload to buffer */ -+ memcpy(fwbuf, &firmware[offset], txlen); -+ } -+ -+ /* Send data */ -+ ret = sdio_writesb(card->func, priv->uap_dev.ioport, -+ fwbuf, tx_blocks * SD_BLOCK_SIZE); -+ -+ if (ret < 0) { -+ PRINTM(ERROR, "FW download, write iomem (%d) failed @ %d\n", i, -+ offset); -+ if (sbi_write_ioreg(priv, CONFIGURATION_REG, 0x04) < 0) { -+ PRINTM(ERROR, "write ioreg failed (CFG)\n"); -+ } -+ } -+ -+ offset += txlen; -+ } while (TRUE); -+ -+ PRINTM(INFO, "\nFW download over, size %d bytes\n", offset); -+ -+ ret = UAP_STATUS_SUCCESS; -+ done: -+#ifdef FW_DOWNLOAD_SPEED -+ tv2 = get_utimeofday(); -+ PRINTM(INFO, "FW: %ld.%03ld.%03ld ", tv1 / 1000000, -+ (tv1 % 1000000) / 1000, tv1 % 1000); -+ PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000, -+ (tv2 % 1000000) / 1000, tv2 % 1000); -+ tv2 -= tv1; -+ PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000, -+ (tv2 % 1000000) / 1000, tv2 % 1000); -+#endif -+ sdio_release_host(card->func); -+ if (tmpfwbuf) -+ kfree(tmpfwbuf); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function checks if the firmware is ready to accept -+ * command or not. -+ * -+ * @param priv A pointer to uap_private structure -+ * @param pollnum Poll number -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_check_fw_status(uap_private * priv, int pollnum) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret = UAP_STATUS_SUCCESS; -+ u16 firmwarestat; -+ int tries; -+ -+ ENTER(); -+ -+ sdio_claim_host(card->func); -+ -+ /* Wait for firmware initialization event */ -+ for (tries = 0; tries < pollnum; tries++) { -+ if ((ret = sd_read_firmware_status(priv, &firmwarestat)) < 0) -+ continue; -+ if (firmwarestat == FIRMWARE_READY) { -+ ret = UAP_STATUS_SUCCESS; -+ break; -+ } else { -+ mdelay(10); -+ ret = UAP_STATUS_FAILURE; -+ } -+ } -+ -+ if (ret < 0) -+ goto done; -+ -+ ret = UAP_STATUS_SUCCESS; -+ sd_get_rx_unit(priv); -+ -+ done: -+ sdio_release_host(card->func); -+ -+ LEAVE(); -+ return ret; -+} -+ -+/** -+ * @brief This function set bus clock on/off -+ * -+ * @param priv A pointer to uap_private structure -+ * @param option TRUE--on , FALSE--off -+ * @return UAP_STATUS_SUCCESS -+ */ -+#if 0 -+static int -+sbi_set_bus_clock(uap_private * priv, u8 option) -+{ -+ ENTER(); -+ LEAVE(); -+ return UAP_STATUS_SUCCESS; -+} -+#endif -+ -+/** -+ * @brief This function wakeup firmware -+ * -+ * @param priv A pointer to uap_private structure -+ * @return UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE -+ */ -+int -+sbi_wakeup_firmware(uap_private * priv) -+{ -+ struct sdio_mmc_card *card = priv->uap_dev.card; -+ int ret = UAP_STATUS_SUCCESS; -+ -+ ENTER(); -+ -+ if (!card || !card->func) { -+ PRINTM(ERROR, "card or function is NULL!\n"); -+ LEAVE(); -+ return UAP_STATUS_FAILURE; -+ } -+ sdio_claim_host(card->func); -+ sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret); -+ sdio_release_host(card->func); -+ LEAVE(); -+ return ret; -+} -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h 1970-01-01 01:00:00.000000000 +0100 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h 2012-07-31 14:23:04.000000000 +0200 -@@ -0,0 +1,136 @@ -+/** @file uap_sdio_mmc.h -+ * @brief This file contains SDIO IF (interface) module -+ * related macros, enum, and structure. -+ * -+ * Copyright (C) 2007-2009, Marvell International Ltd. -+ * -+ * This software file (the "File") is distributed by Marvell International -+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991 -+ * (the "License"). You may use, redistribute and/or modify this File in -+ * accordance with the terms and conditions of the License, a copy of which -+ * is available along with the File in the gpl.txt file or by writing to -+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. -+ * -+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE -+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about -+ * this warranty disclaimer. -+ * -+ */ -+/**************************************************** -+Change log: -+ 10/10/07: initial version -+****************************************************/ -+ -+#ifndef _UAP_SDIO_MMC_H -+#define _UAP_SDIO_MMC_H -+ -+#include <linux/mmc/sdio.h> -+#include <linux/mmc/sdio_ids.h> -+#include <linux/mmc/sdio_func.h> -+#include <linux/mmc/card.h> -+ -+#include "uap_headers.h" -+ -+/** The number of times to try when waiting for downloaded firmware to -+ become active. (polling the scratch register). */ -+#define MAX_FIRMWARE_POLL_TRIES 100 -+ -+/** Firmware ready */ -+#define FIRMWARE_READY 0xfedc -+ -+/** Number of firmware blocks to transfer */ -+#define FIRMWARE_TRANSFER_NBLOCK 2 -+ -+/* Host Control Registers */ -+/** Host Control Registers : I/O port 0 */ -+#define IO_PORT_0_REG 0x00 -+/** Host Control Registers : I/O port 1 */ -+#define IO_PORT_1_REG 0x01 -+/** Host Control Registers : I/O port 2 */ -+#define IO_PORT_2_REG 0x02 -+ -+/** Host Control Registers : Configuration */ -+#define CONFIGURATION_REG 0x03 -+/** Host Control Registers : Host without Command 53 finish host */ -+#define HOST_WO_CMD53_FINISH_HOST (0x1U << 2) -+/** Host Control Registers : Host power up */ -+#define HOST_POWER_UP (0x1U << 1) -+/** Host Control Registers : Host power down */ -+#define HOST_POWER_DOWN (0x1U << 0) -+ -+/** Host Control Registers : Host interrupt mask */ -+#define HOST_INT_MASK_REG 0x04 -+/** Host Control Registers : Upload host interrupt mask */ -+#define UP_LD_HOST_INT_MASK (0x1U) -+/** Host Control Registers : Download host interrupt mask */ -+#define DN_LD_HOST_INT_MASK (0x2U) -+/** Enable Host interrupt mask */ -+#define HIM_ENABLE (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK) -+/** Disable Host interrupt mask */ -+#define HIM_DISABLE 0xff -+ -+/** Host Control Registers : Host interrupt status */ -+#define HOST_INTSTATUS_REG 0x05 -+/** Host Control Registers : Upload host interrupt status */ -+#define UP_LD_HOST_INT_STATUS (0x1U) -+/** Host Control Registers : Download host interrupt status */ -+#define DN_LD_HOST_INT_STATUS (0x2U) -+ -+/** Host F1 read base 0 */ -+#define HOST_F1_RD_BASE_0 0x10 -+/** Host F1 read base 1 */ -+#define HOST_F1_RD_BASE_1 0x11 -+ -+/** Card Control Registers : Card status register */ -+#define CARD_STATUS_REG 0x20 -+/** Card Control Registers : Card I/O ready */ -+#define CARD_IO_READY (0x1U << 3) -+/** Card Control Registers : CIS card ready */ -+#define CIS_CARD_RDY (0x1U << 2) -+/** Card Control Registers : Upload card ready */ -+#define UP_LD_CARD_RDY (0x1U << 1) -+/** Card Control Registers : Download card ready */ -+#define DN_LD_CARD_RDY (0x1U << 0) -+ -+/** Card Control Registers : Card OCR 0 register */ -+#define CARD_OCR_0_REG 0x34 -+/** Card Control Registers : Card OCR 1 register */ -+#define CARD_OCR_1_REG 0x35 -+ -+/** Firmware status 0 register */ -+#define CARD_FW_STATUS0_REG 0x40 -+/** Firmware status 1 register */ -+#define CARD_FW_STATUS1_REG 0x41 -+/** Rx length register */ -+#define CARD_RX_LEN_REG 0x42 -+/** Rx unit register */ -+#define CARD_RX_UNIT_REG 0x43 -+ -+/** Chip Id Register 0 */ -+#define CARD_CHIP_ID_0_REG 0x801c -+/** Chip Id Register 1 */ -+#define CARD_CHIP_ID_1_REG 0x801d -+ -+#ifdef PXA3XX_DMA_ALIGN -+/** DMA alignment value for PXA3XX platforms */ -+#define PXA3XX_DMA_ALIGNMENT 8 -+/** Macros for Data Alignment : size */ -+#define ALIGN_SZ(p, a) \ -+ (((p) + ((a) - 1)) & ~((a) - 1)) -+ -+/** Macros for Data Alignment : address */ -+#define ALIGN_ADDR(p, a) \ -+ ((((u32)(p)) + (((u32)(a)) - 1)) & ~(((u32)(a)) - 1)) -+#endif /* PXA3XX_DMA_ALIGN */ -+ -+struct sdio_mmc_card -+{ -+ /** sdio_func structure pointer */ -+ struct sdio_func *func; -+ /** uap_private structure pointer */ -+ uap_private *priv; -+}; -+ -+#endif /* _UAP_SDIO_MMC_H */ -diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/Makefile compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/Makefile ---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/Makefile 2012-07-05 03:48:01.000000000 +0200 -+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/Makefile 2012-07-31 14:20:01.343608619 +0200 -@@ -22,6 +22,8 @@ - - obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/ - -+obj-$(CONFIG_LIBERTAS_UAP) += libertas_uap/ -+ - obj-$(CONFIG_ADM8211) += adm8211.o - - obj-$(CONFIG_MWL8K) += mwl8k.o diff --git a/src/patches/compat-wireless_codel-avoid-a-nul-rec_inv_sqrt.patch b/src/patches/compat-wireless_codel-avoid-a-nul-rec_inv_sqrt.patch deleted file mode 100644 index 210a58c..0000000 --- a/src/patches/compat-wireless_codel-avoid-a-nul-rec_inv_sqrt.patch +++ /dev/null @@ -1,68 +0,0 @@ -From patchwork Mon Jul 30 06:52:21 2012 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: codel: refine one condition to avoid a nul rec_inv_sqrt -Date: Sun, 29 Jul 2012 20:52:21 -0000 -From: Eric Dumazet eric.dumazet@gmail.com -X-Patchwork-Id: 173968 -Message-Id: 1343631141.2626.13293.camel@edumazet-glaptop -To: David Miller davem@davemloft.net -Cc: netdev netdev@vger.kernel.org, Anton Mich lp2s1h@gmail.com - -From: Eric Dumazet edumazet@google.com - -One condition before codel_Newton_step() was not good if -we never left the dropping state for a flow. As a result -rec_inv_sqrt was 0, instead of the ~0 initial value. - -codel control law was then set to a very aggressive mode, dropping -many packets before reaching 'target' and recovering from this problem. - -To keep codel_vars_init() as efficient as possible, refine -the condition to make sure rec_inv_sqrt initial value is correct - -Many thanks to Anton Mich for discovering the issue and suggesting -a fix. - -Reported-by: Anton Mich lp2s1h@gmail.com -Signed-off-by: Eric Dumazet edumazet@google.com - ---- -include/net/codel.h | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - - - --- -To unsubscribe from this list: send the line "unsubscribe netdev" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html - -diff --git a/include/net/codel.h b/include/net/codel.h -index 550debf..389cf62 100644 ---- a/include/net/codel.h -+++ b/include/net/codel.h -@@ -305,6 +305,8 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch, - } - } - } else if (drop) { -+ u32 delta; -+ - if (params->ecn && INET_ECN_set_ce(skb)) { - stats->ecn_mark++; - } else { -@@ -320,9 +322,11 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch, - * assume that the drop rate that controlled the queue on the - * last cycle is a good starting point to control it now. - */ -- if (codel_time_before(now - vars->drop_next, -+ delta = vars->count - vars->lastcount; -+ if (delta > 1 && -+ codel_time_before(now - vars->drop_next, - 16 * params->interval)) { -- vars->count = (vars->count - vars->lastcount) | 1; -+ vars->count = delta; - /* we dont care if rec_inv_sqrt approximation - * is not very precise : - * Next Newton steps will correct it quadratically. diff --git a/src/patches/dhcp-3.1_linux3.patch b/src/patches/dhcp-3.1_linux3.patch deleted file mode 100644 index 44edb41..0000000 --- a/src/patches/dhcp-3.1_linux3.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -Naur dhcp-3.1-ESV-R3.org/configure dhcp-3.1-ESV-R3/configure ---- dhcp-3.1-ESV-R3.org/configure 2005-03-17 21:14:55.000000000 +0100 -+++ dhcp-3.1-ESV-R3/configure 2012-06-17 12:19:29.000000000 +0200 -@@ -104,6 +104,7 @@ - 2) sysname=linux-2.2 ;; - *) sysname=linux-2.2 ;; - esac;; -+ 3) sysname=linux-2.2 ;; - esac;; - SunOS) - release=`uname -r` diff --git a/src/patches/glibc-arm-dont-use-swp.patch b/src/patches/glibc-arm-dont-use-swp.patch deleted file mode 100644 index 293c20c..0000000 --- a/src/patches/glibc-arm-dont-use-swp.patch +++ /dev/null @@ -1,305 +0,0 @@ -commit 1ba025a9a21eda65d8c36cc0dbb51d214a3ebb1a -Author: Daniel Jacobowitz dan@codesourcery.com -Date: Mon Jun 2 01:57:03 2008 +0000 - - 2008-06-01 Paul Brook paul@codesourcery.com - Zack Weinberg zack@codesourcery.com - Daniel Jacobowitz dan@codesourcery.com - - * sysdeps/arm/nptl/pthread_spin_lock.S, - sysdeps/arm/nptl/pthread_spin_trylock.S: Delete. - * sysdeps/arm/nptl/pthread_spin_lock.c, - sysdeps/arm/nptl/pthread_spin_trylock.c: New files using - atomic_compare_and_exchange_val_acq to take spinlocks. - * sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h (lll_trylock, - lll_cond_trylock): Use atomic_compare_and_exchange_val_acq. - (__lll_trylock, __lll_cond_trylock): Delete. - * sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h - (atomic_exchange_acq): Delete. - (atomic_full_barrier): Define. - (__arch_compare_and_exchange_val_32_acq): Use named operands. - * sysdeps/unix/sysv/linux/arm/eabi/configure.in: Update - arch_minimum_kernel to 2.6.16. - * sysdeps/unix/sysv/linux/arm/eabi/configure: Regenerated. - -diff --git a/sysdeps/arm/nptl/pthread_spin_lock.S b/sysdeps/arm/nptl/pthread_spin_lock.S -deleted file mode 100644 -index bd6adf7..0000000 ---- a/sysdeps/arm/nptl/pthread_spin_lock.S -+++ /dev/null -@@ -1,31 +0,0 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -- This file is part of the GNU C Library. -- -- The GNU C Library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- The GNU C Library 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 -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with the GNU C Library; if not, write to the Free -- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -- 02111-1307 USA. */ -- --#include <sysdep.h> -- -- .text -- .align 4 -- --ENTRY (pthread_spin_lock) -- mov r1, #1 --1: swp r2, r1, [r0] -- teq r2, #0 -- bne 1b -- mov r0, #0 -- PSEUDO_RET_NOERRNO --END (pthread_spin_lock) -diff --git a/sysdeps/arm/nptl/pthread_spin_lock.c b/sysdeps/arm/nptl/pthread_spin_lock.c -new file mode 100644 -index 0000000..1217b89 ---- /dev/null -+++ b/sysdeps/arm/nptl/pthread_spin_lock.c -@@ -0,0 +1,30 @@ -+/* Copyright (C) 2008 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include <atomic.h> -+#include "pthreadP.h" -+ -+int -+pthread_spin_lock (pthread_spinlock_t *lock) -+{ -+ while (atomic_compare_and_exchange_val_acq (lock, 1, 0) != 0) -+ while (*lock != 0) -+ ; -+ -+ return 0; -+} -diff --git a/sysdeps/arm/nptl/pthread_spin_trylock.S b/sysdeps/arm/nptl/pthread_spin_trylock.S -deleted file mode 100644 -index 8593150..0000000 ---- a/sysdeps/arm/nptl/pthread_spin_trylock.S -+++ /dev/null -@@ -1,34 +0,0 @@ --/* Copyright (C) 2005 Free Software Foundation, Inc. -- This file is part of the GNU C Library. -- -- The GNU C Library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- The GNU C Library 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 -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with the GNU C Library; if not, write to the Free -- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -- 02111-1307 USA. */ -- --#define _ERRNO_H 1 --#include <bits/errno.h> -- --#include <sysdep.h> -- -- .text -- .align 4 -- --ENTRY (pthread_spin_trylock) -- mov r1, #1 -- swp r2, r1, [r0] -- teq r2, #0 -- moveq r0, #0 -- movne r0, #EBUSY -- PSEUDO_RET_NOERRNO --END (pthread_spin_trylock) -diff --git a/sysdeps/arm/nptl/pthread_spin_trylock.c b/sysdeps/arm/nptl/pthread_spin_trylock.c -new file mode 100644 -index 0000000..fb998d2 ---- /dev/null -+++ b/sysdeps/arm/nptl/pthread_spin_trylock.c -@@ -0,0 +1,27 @@ -+/* Copyright (C) 2008 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library 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 -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, write to the Free -+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -+ 02111-1307 USA. */ -+ -+#include <errno.h> -+#include <atomic.h> -+#include "pthreadP.h" -+ -+int -+pthread_spin_trylock (pthread_spinlock_t *lock) -+{ -+ return atomic_compare_and_exchange_val_acq (lock, 1, 0) ? EBUSY : 0; -+} -diff --git a/sysdeps/unix/sysv/linux/arm/eabi/configure b/sysdeps/unix/sysv/linux/arm/eabi/configure -index ab83048..28fb9ef 100644 ---- a/sysdeps/unix/sysv/linux/arm/eabi/configure -+++ b/sysdeps/unix/sysv/linux/arm/eabi/configure -@@ -1,5 +1,5 @@ - # This file is generated from configure.in by Autoconf. DO NOT EDIT! - # Local configure fragment for sysdeps/unix/sysv/linux/arm/eabi. - --arch_minimum_kernel=2.6.14 -+arch_minimum_kernel=2.6.16 - libc_cv_gcc_unwind_find_fde=no -diff --git a/sysdeps/unix/sysv/linux/arm/eabi/configure.in b/sysdeps/unix/sysv/linux/arm/eabi/configure.in -index 83aa8fc..d1fb7f4 100644 ---- a/sysdeps/unix/sysv/linux/arm/eabi/configure.in -+++ b/sysdeps/unix/sysv/linux/arm/eabi/configure.in -@@ -1,5 +1,5 @@ - GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. - # Local configure fragment for sysdeps/unix/sysv/linux/arm/eabi. - --arch_minimum_kernel=2.6.14 -+arch_minimum_kernel=2.6.16 - libc_cv_gcc_unwind_find_fde=no -diff --git a/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h b/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h -index 71ed714..247ddd3 100644 ---- a/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h -+++ b/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h -@@ -37,22 +37,12 @@ typedef uintmax_t uatomic_max_t; - - void __arm_link_error (void); - --#define atomic_exchange_acq(mem, newvalue) \ -- ({ __typeof (*mem) result; \ -- if (sizeof (*mem) == 1) \ -- __asm__ __volatile__ ("swpb %0, %1, [%2]" \ -- : "=&r,&r" (result) \ -- : "r,0" (newvalue), "r,r" (mem) : "memory"); \ -- else if (sizeof (*mem) == 4) \ -- __asm__ __volatile__ ("swp %0, %1, [%2]" \ -- : "=&r,&r" (result) \ -- : "r,0" (newvalue), "r,r" (mem) : "memory"); \ -- else \ -- { \ -- result = 0; \ -- abort (); \ -- } \ -- result; }) -+#define atomic_full_barrier() \ -+ __asm__ __volatile__ \ -+ ("mov\tip, #0xffff0fff\n\t" \ -+ "mov\tlr, pc\n\t" \ -+ "add\tpc, ip, #(0xffff0fa0 - 0xffff0fff)" \ -+ : : : "ip", "lr", "cc", "memory"); - - /* Atomic compare and exchange. This sequence relies on the kernel to - provide a compare and exchange operation which is atomic on the -@@ -76,18 +66,19 @@ void __arm_link_error (void); - register __typeof (oldval) a_tmp asm ("r3"); \ - register __typeof (oldval) a_oldval2 asm ("r4") = (oldval); \ - __asm__ __volatile__ \ -- ("0:\tldr\t%1,[%3]\n\t" \ -- "cmp\t%1, %4\n\t" \ -+ ("0:\tldr\t%[tmp],[%[ptr]]\n\t" \ -+ "cmp\t%[tmp], %[old2]\n\t" \ - "bne\t1f\n\t" \ -- "mov\t%0, %4\n\t" \ -- "mov\t%1, #0xffff0fff\n\t" \ -+ "mov\t%[old], %[old2]\n\t" \ -+ "mov\t%[tmp], #0xffff0fff\n\t" \ - "mov\tlr, pc\n\t" \ -- "add\tpc, %1, #(0xffff0fc0 - 0xffff0fff)\n\t" \ -+ "add\tpc, %[tmp], #(0xffff0fc0 - 0xffff0fff)\n\t" \ - "bcc\t0b\n\t" \ -- "mov\t%1, %4\n\t" \ -+ "mov\t%[tmp], %[old2]\n\t" \ - "1:" \ -- : "=&r" (a_oldval), "=&r" (a_tmp) \ -- : "r" (a_newval), "r" (a_ptr), "r" (a_oldval2) \ -+ : [old] "=&r" (a_oldval), [tmp] "=&r" (a_tmp) \ -+ : [new] "r" (a_newval), [ptr] "r" (a_ptr), \ -+ [old2] "r" (a_oldval2) \ - : "ip", "lr", "cc", "memory"); \ - a_tmp; }) - -diff --git a/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h b/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h -index f48e867..889f97c 100644 ---- a/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h -+++ b/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h -@@ -126,43 +126,11 @@ - }) - - --static inline int __attribute__((always_inline)) --__lll_mutex_trylock (int *futex) --{ -- int flag = 1, old; -- asm volatile ( -- "\tswp %[old], %[flag], [%[futex]] @ try to take the lock\n" -- "\tcmp %[old], #1 @ check old lock value\n" -- "\tmovlo %[flag], #0 @ if we got it, return 0\n" -- "\tswphi %[flag], %[old], [%[futex]] @ if it was contested,\n" -- " @ restore the contested flag,\n" -- " @ and check whether that won." -- : [futex] "+&r" (futex), [flag] "+&r" (flag), [old] "=&r" (old) -- : : "memory" ); -- -- return flag; --} --#define lll_mutex_trylock(lock) __lll_mutex_trylock (&(lock)) -- -- --static inline int __attribute__((always_inline)) --__lll_mutex_cond_trylock (int *futex) --{ -- int flag = 2, old; -- asm volatile ( -- "\tswp %[old], %[flag], [%[futex]] @ try to take the lock\n" -- "\tcmp %[old], #1 @ check old lock value\n" -- "\tmovlo %[flag], #0 @ if we got it, return 0\n" -- "\tswphi %[flag], %[old], [%[futex]] @ if it was contested,\n" -- " @ restore the contested flag,\n" -- " @ and check whether that won." -- : [futex] "+&r" (futex), [flag] "+&r" (flag), [old] "=&r" (old) -- : : "memory" ); -- -- return flag; --} --#define lll_mutex_cond_trylock(lock) __lll_mutex_cond_trylock (&(lock)) -+#define lll_mutex_trylock(lock) \ -+ atomic_compare_and_exchange_val_acq(&(lock), 1, 0) - -+#define lll_mutex_cond_trylock(lock) \ -+ atomic_compare_and_exchange_val_acq(&(lock), 2, 0) - - #define __lll_robust_trylock(futex, id) \ - (atomic_compare_and_exchange_val_acq (futex, id, 0) != 0) diff --git a/src/patches/grub-gentoo-14.patch b/src/patches/grub-gentoo-14.patch deleted file mode 100644 index d2bb959..0000000 --- a/src/patches/grub-gentoo-14.patch +++ /dev/null @@ -1,16087 +0,0 @@ -diff -Nur grub-0.97/acinclude.m4 grub-0.97-patched/acinclude.m4 ---- grub-0.97/acinclude.m4 2004-04-27 22:48:06.000000000 +0200 -+++ grub-0.97-patched/acinclude.m4 2012-11-11 17:07:12.710729053 +0100 -@@ -57,7 +57,7 @@ - fi - grub_cv_prog_objcopy_absolute=yes - for link_addr in 2000 8000 7C00; do -- if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then : -+ if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} ${LDFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then : - else - AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr]) - fi -diff -Nur grub-0.97/ChangeLog grub-0.97-patched/ChangeLog ---- grub-0.97/ChangeLog 2005-05-08 04:47:02.000000000 +0200 -+++ grub-0.97-patched/ChangeLog 2012-11-11 17:07:12.708728989 +0100 -@@ -1,3 +1,127 @@ -+2008-05-20 Robert Millan rmh@aybabtu.com -+ -+ * netboot/cs89x0.c: Fix license violation. -+ * netboot/cs89x0.h: Likewise. -+ -+2008-04-10 Pavel Roskin proski@gnu.org -+ -+ * configure.ac: Always use "_cv_" in cache variables for -+ compatibility with Autoconf 2.62. -+ -+2008-03-28 Robert Millan rmh@aybabtu.com -+ -+ Surpass 1 TiB disk addressing limit. Note: there are no plans to handle -+ the 2 TiB disk limit in GRUB Legacy, since that would need considerable -+ rework. If you have >2TiB disks, use GRUB 2 instead. -+ -+ * grub/asmstub.c (biosdisk): Add unsigned qualifier to `sector'. -+ * stage2/bios.c (biosdisk): Likewise. -+ * stage2/disk_io.c (rawread, devread, rawwrite, devwrite): Likewise. -+ * stage2/shared.h (rawread, devread, rawwrite, devwrite): Likewise. -+ * lib/device.c (get_drive_geometry): Replace BLKGETSIZE with -+ BLKGETSIZE64. -+ -+2007-10-29 Pavel Roskin proski@gnu.org -+ -+ * configure.ac: Test if '--build-id=none' is supported by the -+ linker and add it to LDFLAGS if possible. Build ID causes -+ objcopy to generate huge binary files. -+ * aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Use LDFLAGS when -+ linking, so that build ID doesn't break the test. -+ * stage1/Makefile.am: Preserve LDFLAGS, use stage1_exec_LDFLAGS. -+ -+2007-02-22 Pavel Roskin proski@gnu.org -+ -+ * stage2/iso9660.h: Remove unnecessary packed attributes. -+ -+2007-02-22 Robert Millan rmh@aybabtu.com -+ -+ * util/mkbimage: Update my email address, and remove my name from -+ some places where unnecessary credit is given. -+ -+2006-09-10 Pavel Roskin proski@gnu.org -+ -+ * netboot/natsemi.c: Fix compile error with gcc 4.1.1. Cast -+ cannot make a variable volatile - it should be declared as such. -+ * netboot/sis900.c: Likewise. -+ -+2006-09-08 Pavel Roskin proski@gnu.org -+ -+ * netboot/etherboot.h: Remove incorrect extern declarations of -+ the variables later declared static. Move BOOTP_DATA_ADDR ... -+ * netboot/main.c: ... here. Eliminate end_of_rfc1533 - it's -+ write-only. -+ -+2006-06-24 Yoshinori K. Okuji okuji@enbug.org -+ -+ * docs/grub.texi: Changed the license term to the GNU Free -+ Documentation License 1.2. -+ -+ * docs/multiboot.texi: Reformatted to show the license term -+ and the version number explicitly. -+ -+ * docs/fdl.texi: New file. -+ -+ * docs/Makefile.am (grub_TEXINFOS): Added fdl.texi. -+ -+2006-06-24 Robert Millan robertmh@gnu.org -+ -+ * lib/device.c (write_to_partition): /dev/ataraid/ and /dev/rd/ -+ partitions have a "p" prefix. Add it. -+ -+2006-06-24 Robert Millan robertmh@gnu.org -+ -+ * lib/device.c (get_i2o_disk_name): New function. -+ (init_device_map) [__linux__]: Add support for I2O devices. -+ -+2006-05-02 Pavel Roskin proski@gnu.org -+ -+ * stage2/stage2.c (run_menu): Fix "savedefault" to save only top -+ level menu positions. Remember current position when calling a -+ submenu. Don't recalculate it when booting from a submenu. -+ -+ * grub/main.c (main): Make sure the boot drive number doesn't -+ exceed 255. -+ -+2006-05-02 Vesa Jaaskelainen chaac@nic.fi -+ -+ * stage2/shared.h (vbe_mode): Back ported aligment fix from GRUB 2 -+ to GRUB Legacy. Problem reported by Gerardo Richarte. -+ -+2006-04-23 Robert Millan robertmh@gnu.org -+ -+ * grub/asmstub.c (get_diskinfo): Optimize sysctl routine. -+ -+2006-04-20 Robert Millan robertmh@gnu.org -+ -+ Fixes for kernel of FreeBSD: -+ * grub/asmstub.c (get_diskinfo): Toggle "kern.geom.debugflags" sysctl -+ before opening a device for writing. -+ * util/grub-install.in: Devices don't have this "r" prefix anymore. -+ -+2006-04-16 Yoshinori K. Okuji okuji@enbug.org -+ -+ * docs/multiboot.texi: Correct the offset of address -+ fields. Reported by Jeroen Dekkers. -+ -+2006-03-21 Yoshinori K. Okuji okuji@enbug.org -+ -+ * stage2/builtins.c (setup_func): Specify the size of DEVICE to -+ grub_strncat instead of a strange number 256. Reported by Vitaly -+ Fertman vitaly@namesys.com. -+ -+2005-09-29 Yoshinori K. Okuji okuji@enbug.org -+ -+ * docs/multiboot.texi: Fix a bug in the byte order of -+ boot_device. I hope this won't affect any OS image. -+ Increased the version number to 0.6.94. -+ -+2005-09-28 Yoshinori K. Okuji okuji@enbug.org -+ -+ * stage2/boot.c (load_image): Even if an OS image is an ELF -+ object, use the a.out kludge if MULTIBOOT_AOUT_KLUDGE is -+ specified. -+ - 2005-05-08 Yoshinori K. Okuji okuji@enbug.org - - * configure.ac (AC_INIT): Upgraded to 0.97. -diff -Nur grub-0.97/configure.ac grub-0.97-patched/configure.ac ---- grub-0.97/configure.ac 2005-05-08 04:36:03.000000000 +0200 -+++ grub-0.97-patched/configure.ac 2012-11-11 17:07:12.752730394 +0100 -@@ -21,8 +21,12 @@ - AC_CANONICAL_HOST - - case "$host_cpu" in --i[[3456]]86) host_cpu=i386 ;; --x86_64) host_cpu=x86_64 ;; -+i[[3456]]86) -+ STAGE_MARCH="-march=$host_cpu" -+ host_cpu=i386 ;; -+x86_64) -+ STAGE_MARCH="-march=i686" -+ host_cpu=x86_64 ;; - *) AC_MSG_ERROR([unsupported CPU type]) ;; - esac - -@@ -56,12 +60,7 @@ - - AC_CHECK_TOOL(CC, gcc) - AC_PROG_CC --# We need this for older versions of Autoconf. --_AM_DEPENDENCIES(CC) -- --dnl Because recent automake complains about AS, set it here. --CCAS="$CC" --AC_SUBST(CCAS) -+AM_PROG_AS - - AC_ARG_WITH(binutils, - [ --with-binutils=DIR search the directory DIR to find binutils]) -@@ -86,13 +85,13 @@ - fi - STAGE1_CFLAGS="-O2" - GRUB_CFLAGS="-O2" -- AC_CACHE_CHECK([whether optimization for size works], size_flag, [ -+ AC_CACHE_CHECK([whether optimization for size works], grub_cv_cc_Os, [ - saved_CFLAGS=$CFLAGS - CFLAGS="-Os -g" -- AC_TRY_COMPILE(, , size_flag=yes, size_flag=no) -+ AC_TRY_COMPILE(, , grub_cv_cc_Os=yes, grub_cv_cc_Os=no) - CFLAGS=$saved_CFLAGS - ]) -- if test "x$size_flag" = xyes; then -+ if test "x$grub_cv_cc_Os" = xyes; then - STAGE2_CFLAGS="-Os" - else - STAGE2_CFLAGS="-O2 -fno-strength-reduce -fno-unroll-loops" -@@ -100,21 +99,38 @@ - # OpenBSD has a GCC extension for protecting applications from - # stack smashing attacks, but GRUB doesn't want this feature. - AC_CACHE_CHECK([whether gcc has -fno-stack-protector], -- no_stack_protector_flag, [ -+ grub_cv_cc_no_stack_protector, [ - saved_CFLAGS=$CFLAGS - CFLAGS="-fno-stack-protector" - AC_TRY_COMPILE(, - , -- no_stack_protector_flag=yes, -- no_stack_protector_flag=no) -+ grub_cv_cc_no_stack_protector=yes, -+ grub_cv_cc_no_stack_protector=no) - CFLAGS=$saved_CFLAGS - ]) -- if test "x$no_stack_protector_flag" = xyes; then -+ if test "x$grub_cv_cc_no_stack_protector" = xyes; then - STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-stack-protector" - fi -+ # Position Independent Executables, but GRUB doesn't want this feature. -+ AC_CACHE_CHECK([whether gcc has -fPIE on as default], grub_cv_cc_fpie, [ -+ AC_TRY_COMPILE(,[ -+ #if ! defined (__PIC__) || ! defined (__PIE__) -+ #error -+ #endif -+ ], -+ grub_cv_cc_fpie=yes, -+ grub_cv_cc_fpie=no) -+ ]) -+ if test "x$grub_cv_cc_fpie" = xyes; then -+ STAGE1_CFLAGS="$STAGE1_CFLAGS -nopie" -+ STAGE2_CFLAGS="$STAGE2_CFLAGS -nopie" -+ fi - fi - fi - -+STAGE1_CFLAGS="$STAGE1_CFLAGS -fno-strict-aliasing $STAGE_MARCH" -+STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-strict-aliasing $STAGE_MARCH" -+GRUB_CFLAGS="$GRUB_CFLAGS -fno-strict-aliasing" - AC_SUBST(STAGE1_CFLAGS) - AC_SUBST(STAGE2_CFLAGS) - AC_SUBST(GRUB_CFLAGS) -@@ -123,33 +139,44 @@ - CPPFLAGS="$CPPFLAGS -Wall -Wmissing-prototypes -Wunused -Wshadow" - CPPFLAGS="$CPPFLAGS -Wpointer-arith" - --AC_CACHE_CHECK([whether -Wundef works], undef_flag, [ -+AC_CACHE_CHECK([whether -Wundef works], grub_cv_cc_Wundef, [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="-Wundef" -- AC_TRY_COMPILE(, , undef_flag=yes, undef_flag=no) -+ AC_TRY_COMPILE(, , grub_cv_cc_Wundef=yes, grub_cv_cc_Wundef=no) - CPPFLAGS="$saved_CPPFLAGS" - ]) - - # The options `-falign-*' are supported by gcc 3.0 or later. - # Probably it is sufficient to only check for -falign-loops. --AC_CACHE_CHECK([whether -falign-loops works], [falign_loop_flag], [ -+AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [ - saved_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="-falign-loops=1" -- AC_TRY_COMPILE(, , [falign_loop_flag=yes], [falign_loop_flag=no]) -+ AC_TRY_COMPILE(, , [grub_cv_cc_falign_loop=yes], [grub_cv_cc_falign_loop=no]) - CPPFLAGS="$saved_CPPFLAGS" - ]) - - # Force no alignment to save space. --if test "x$falign_loop_flag" = xyes; then -+if test "x$grub_cv_cc_falign_loop" = xyes; then - CPPFLAGS="$CPPFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1" - else - CPPFLAGS="$CPPFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1" - fi - --if test "x$undef_flag" = xyes; then -+if test "x$grub_cv_cc_Wundef" = xyes; then - CPPFLAGS="$CPPFLAGS -Wundef" - fi - -+# Check if build ID can be disabled in the linker -+AC_MSG_CHECKING([whether linker accepts `--build-id=none']) -+save_LDFLAGS="$LDFLAGS" -+LDFLAGS="$LDFLAGS -Wl,--build-id=none" -+AC_TRY_LINK(, , build_id_flag=yes, build_id_flag=no) -+AC_MSG_RESULT([$build_id_flag]) -+LDFLAGS="$save_LDFLAGS" -+if test "x$build_id_flag" = xyes; then -+ LDFLAGS="$LDFLAGS -Wl,--build-id=none" -+fi -+ - if test "x$with_binutils" != x; then - dnl AC_PATH_TOOL(OBJCOPY, objcopy, , "$with_binutils:$PATH") - AC_PATH_PROG(OBJCOPY, objcopy, , "$with_binutils:$PATH") -@@ -595,6 +622,11 @@ - [ --enable-diskless enable diskless support]) - AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes) - -+dnl Graphical splashscreen support -+AC_ARG_ENABLE(graphics, -+ [ --disable-graphics disable graphics terminal support]) -+AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno) -+ - dnl Hercules terminal - AC_ARG_ENABLE(hercules, - [ --disable-hercules disable hercules terminal support]) -diff -Nur grub-0.97/docs/fdl.texi grub-0.97-patched/docs/fdl.texi ---- grub-0.97/docs/fdl.texi 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/docs/fdl.texi 2012-11-11 17:07:12.712729117 +0100 -@@ -0,0 +1,452 @@ -+ -+@node GNU Free Documentation License -+@appendixsec GNU Free Documentation License -+ -+@cindex FDL, GNU Free Documentation License -+@center Version 1.2, November 2002 -+ -+@display -+Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc. -+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ -+Everyone is permitted to copy and distribute verbatim copies -+of this license document, but changing it is not allowed. -+@end display -+ -+@enumerate 0 -+@item -+PREAMBLE -+ -+The purpose of this License is to make a manual, textbook, or other -+functional and useful document @dfn{free} in the sense of freedom: to -+assure everyone the effective freedom to copy and redistribute it, -+with or without modifying it, either commercially or noncommercially. -+Secondarily, this License preserves for the author and publisher a way -+to get credit for their work, while not being considered responsible -+for modifications made by others. -+ -+This License is a kind of ``copyleft'', which means that derivative -+works of the document must themselves be free in the same sense. It -+complements the GNU General Public License, which is a copyleft -+license designed for free software. -+ -+We have designed this License in order to use it for manuals for free -+software, because free software needs free documentation: a free -+program should come with manuals providing the same freedoms that the -+software does. But this License is not limited to software manuals; -+it can be used for any textual work, regardless of subject matter or -+whether it is published as a printed book. We recommend this License -+principally for works whose purpose is instruction or reference. -+ -+@item -+APPLICABILITY AND DEFINITIONS -+ -+This License applies to any manual or other work, in any medium, that -+contains a notice placed by the copyright holder saying it can be -+distributed under the terms of this License. Such a notice grants a -+world-wide, royalty-free license, unlimited in duration, to use that -+work under the conditions stated herein. The ``Document'', below, -+refers to any such manual or work. Any member of the public is a -+licensee, and is addressed as ``you''. You accept the license if you -+copy, modify or distribute the work in a way requiring permission -+under copyright law. -+ -+A ``Modified Version'' of the Document means any work containing the -+Document or a portion of it, either copied verbatim, or with -+modifications and/or translated into another language. -+ -+A ``Secondary Section'' is a named appendix or a front-matter section -+of the Document that deals exclusively with the relationship of the -+publishers or authors of the Document to the Document's overall -+subject (or to related matters) and contains nothing that could fall -+directly within that overall subject. (Thus, if the Document is in -+part a textbook of mathematics, a Secondary Section may not explain -+any mathematics.) The relationship could be a matter of historical -+connection with the subject or with related matters, or of legal, -+commercial, philosophical, ethical or political position regarding -+them. -+ -+The ``Invariant Sections'' are certain Secondary Sections whose titles -+are designated, as being those of Invariant Sections, in the notice -+that says that the Document is released under this License. If a -+section does not fit the above definition of Secondary then it is not -+allowed to be designated as Invariant. The Document may contain zero -+Invariant Sections. If the Document does not identify any Invariant -+Sections then there are none. -+ -+The ``Cover Texts'' are certain short passages of text that are listed, -+as Front-Cover Texts or Back-Cover Texts, in the notice that says that -+the Document is released under this License. A Front-Cover Text may -+be at most 5 words, and a Back-Cover Text may be at most 25 words. -+ -+A ``Transparent'' copy of the Document means a machine-readable copy, -+represented in a format whose specification is available to the -+general public, that is suitable for revising the document -+straightforwardly with generic text editors or (for images composed of -+pixels) generic paint programs or (for drawings) some widely available -+drawing editor, and that is suitable for input to text formatters or -+for automatic translation to a variety of formats suitable for input -+to text formatters. A copy made in an otherwise Transparent file -+format whose markup, or absence of markup, has been arranged to thwart -+or discourage subsequent modification by readers is not Transparent. -+An image format is not Transparent if used for any substantial amount -+of text. A copy that is not ``Transparent'' is called ``Opaque''. -+ -+Examples of suitable formats for Transparent copies include plain -+@sc{ascii} without markup, Texinfo input format, La@TeX{} input -+format, @acronym{SGML} or @acronym{XML} using a publicly available -+@acronym{DTD}, and standard-conforming simple @acronym{HTML}, -+PostScript or @acronym{PDF} designed for human modification. Examples -+of transparent image formats include @acronym{PNG}, @acronym{XCF} and -+@acronym{JPG}. Opaque formats include proprietary formats that can be -+read and edited only by proprietary word processors, @acronym{SGML} or -+@acronym{XML} for which the @acronym{DTD} and/or processing tools are -+not generally available, and the machine-generated @acronym{HTML}, -+PostScript or @acronym{PDF} produced by some word processors for -+output purposes only. -+ -+The ``Title Page'' means, for a printed book, the title page itself, -+plus such following pages as are needed to hold, legibly, the material -+this License requires to appear in the title page. For works in -+formats which do not have any title page as such, ``Title Page'' means -+the text near the most prominent appearance of the work's title, -+preceding the beginning of the body of the text. -+ -+A section ``Entitled XYZ'' means a named subunit of the Document whose -+title either is precisely XYZ or contains XYZ in parentheses following -+text that translates XYZ in another language. (Here XYZ stands for a -+specific section name mentioned below, such as ``Acknowledgements'', -+``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' -+of such a section when you modify the Document means that it remains a -+section ``Entitled XYZ'' according to this definition. -+ -+The Document may include Warranty Disclaimers next to the notice which -+states that this License applies to the Document. These Warranty -+Disclaimers are considered to be included by reference in this -+License, but only as regards disclaiming warranties: any other -+implication that these Warranty Disclaimers may have is void and has -+no effect on the meaning of this License. -+ -+@item -+VERBATIM COPYING -+ -+You may copy and distribute the Document in any medium, either -+commercially or noncommercially, provided that this License, the -+copyright notices, and the license notice saying this License applies -+to the Document are reproduced in all copies, and that you add no other -+conditions whatsoever to those of this License. You may not use -+technical measures to obstruct or control the reading or further -+copying of the copies you make or distribute. However, you may accept -+compensation in exchange for copies. If you distribute a large enough -+number of copies you must also follow the conditions in section 3. -+ -+You may also lend copies, under the same conditions stated above, and -+you may publicly display copies. -+ -+@item -+COPYING IN QUANTITY -+ -+If you publish printed copies (or copies in media that commonly have -+printed covers) of the Document, numbering more than 100, and the -+Document's license notice requires Cover Texts, you must enclose the -+copies in covers that carry, clearly and legibly, all these Cover -+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -+the back cover. Both covers must also clearly and legibly identify -+you as the publisher of these copies. The front cover must present -+the full title with all words of the title equally prominent and -+visible. You may add other material on the covers in addition. -+Copying with changes limited to the covers, as long as they preserve -+the title of the Document and satisfy these conditions, can be treated -+as verbatim copying in other respects. -+ -+If the required texts for either cover are too voluminous to fit -+legibly, you should put the first ones listed (as many as fit -+reasonably) on the actual cover, and continue the rest onto adjacent -+pages. -+ -+If you publish or distribute Opaque copies of the Document numbering -+more than 100, you must either include a machine-readable Transparent -+copy along with each Opaque copy, or state in or with each Opaque copy -+a computer-network location from which the general network-using -+public has access to download using public-standard network protocols -+a complete Transparent copy of the Document, free of added material. -+If you use the latter option, you must take reasonably prudent steps, -+when you begin distribution of Opaque copies in quantity, to ensure -+that this Transparent copy will remain thus accessible at the stated -+location until at least one year after the last time you distribute an -+Opaque copy (directly or through your agents or retailers) of that -+edition to the public. -+ -+It is requested, but not required, that you contact the authors of the -+Document well before redistributing any large number of copies, to give -+them a chance to provide you with an updated version of the Document. -+ -+@item -+MODIFICATIONS -+ -+You may copy and distribute a Modified Version of the Document under -+the conditions of sections 2 and 3 above, provided that you release -+the Modified Version under precisely this License, with the Modified -+Version filling the role of the Document, thus licensing distribution -+and modification of the Modified Version to whoever possesses a copy -+of it. In addition, you must do these things in the Modified Version: -+ -+@enumerate A -+@item -+Use in the Title Page (and on the covers, if any) a title distinct -+from that of the Document, and from those of previous versions -+(which should, if there were any, be listed in the History section -+of the Document). You may use the same title as a previous version -+if the original publisher of that version gives permission. -+ -+@item -+List on the Title Page, as authors, one or more persons or entities -+responsible for authorship of the modifications in the Modified -+Version, together with at least five of the principal authors of the -+Document (all of its principal authors, if it has fewer than five), -+unless they release you from this requirement. -+ -+@item -+State on the Title page the name of the publisher of the -+Modified Version, as the publisher. -+ -+@item -+Preserve all the copyright notices of the Document. -+ -+@item -+Add an appropriate copyright notice for your modifications -+adjacent to the other copyright notices. -+ -+@item -+Include, immediately after the copyright notices, a license notice -+giving the public permission to use the Modified Version under the -+terms of this License, in the form shown in the Addendum below. -+ -+@item -+Preserve in that license notice the full lists of Invariant Sections -+and required Cover Texts given in the Document's license notice. -+ -+@item -+Include an unaltered copy of this License. -+ -+@item -+Preserve the section Entitled ``History'', Preserve its Title, and add -+to it an item stating at least the title, year, new authors, and -+publisher of the Modified Version as given on the Title Page. If -+there is no section Entitled ``History'' in the Document, create one -+stating the title, year, authors, and publisher of the Document as -+given on its Title Page, then add an item describing the Modified -+Version as stated in the previous sentence. -+ -+@item -+Preserve the network location, if any, given in the Document for -+public access to a Transparent copy of the Document, and likewise -+the network locations given in the Document for previous versions -+it was based on. These may be placed in the ``History'' section. -+You may omit a network location for a work that was published at -+least four years before the Document itself, or if the original -+publisher of the version it refers to gives permission. -+ -+@item -+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve -+the Title of the section, and preserve in the section all the -+substance and tone of each of the contributor acknowledgements and/or -+dedications given therein. -+ -+@item -+Preserve all the Invariant Sections of the Document, -+unaltered in their text and in their titles. Section numbers -+or the equivalent are not considered part of the section titles. -+ -+@item -+Delete any section Entitled ``Endorsements''. Such a section -+may not be included in the Modified Version. -+ -+@item -+Do not retitle any existing section to be Entitled ``Endorsements'' or -+to conflict in title with any Invariant Section. -+ -+@item -+Preserve any Warranty Disclaimers. -+@end enumerate -+ -+If the Modified Version includes new front-matter sections or -+appendices that qualify as Secondary Sections and contain no material -+copied from the Document, you may at your option designate some or all -+of these sections as invariant. To do this, add their titles to the -+list of Invariant Sections in the Modified Version's license notice. -+These titles must be distinct from any other section titles. -+ -+You may add a section Entitled ``Endorsements'', provided it contains -+nothing but endorsements of your Modified Version by various -+parties---for example, statements of peer review or that the text has -+been approved by an organization as the authoritative definition of a -+standard. -+ -+You may add a passage of up to five words as a Front-Cover Text, and a -+passage of up to 25 words as a Back-Cover Text, to the end of the list -+of Cover Texts in the Modified Version. Only one passage of -+Front-Cover Text and one of Back-Cover Text may be added by (or -+through arrangements made by) any one entity. If the Document already -+includes a cover text for the same cover, previously added by you or -+by arrangement made by the same entity you are acting on behalf of, -+you may not add another; but you may replace the old one, on explicit -+permission from the previous publisher that added the old one. -+ -+The author(s) and publisher(s) of the Document do not by this License -+give permission to use their names for publicity for or to assert or -+imply endorsement of any Modified Version. -+ -+@item -+COMBINING DOCUMENTS -+ -+You may combine the Document with other documents released under this -+License, under the terms defined in section 4 above for modified -+versions, provided that you include in the combination all of the -+Invariant Sections of all of the original documents, unmodified, and -+list them all as Invariant Sections of your combined work in its -+license notice, and that you preserve all their Warranty Disclaimers. -+ -+The combined work need only contain one copy of this License, and -+multiple identical Invariant Sections may be replaced with a single -+copy. If there are multiple Invariant Sections with the same name but -+different contents, make the title of each such section unique by -+adding at the end of it, in parentheses, the name of the original -+author or publisher of that section if known, or else a unique number. -+Make the same adjustment to the section titles in the list of -+Invariant Sections in the license notice of the combined work. -+ -+In the combination, you must combine any sections Entitled ``History'' -+in the various original documents, forming one section Entitled -+``History''; likewise combine any sections Entitled ``Acknowledgements'', -+and any sections Entitled ``Dedications''. You must delete all -+sections Entitled ``Endorsements.'' -+ -+@item -+COLLECTIONS OF DOCUMENTS -+ -+You may make a collection consisting of the Document and other documents -+released under this License, and replace the individual copies of this -+License in the various documents with a single copy that is included in -+the collection, provided that you follow the rules of this License for -+verbatim copying of each of the documents in all other respects. -+ -+You may extract a single document from such a collection, and distribute -+it individually under this License, provided you insert a copy of this -+License into the extracted document, and follow this License in all -+other respects regarding verbatim copying of that document. -+ -+@item -+AGGREGATION WITH INDEPENDENT WORKS -+ -+A compilation of the Document or its derivatives with other separate -+and independent documents or works, in or on a volume of a storage or -+distribution medium, is called an ``aggregate'' if the copyright -+resulting from the compilation is not used to limit the legal rights -+of the compilation's users beyond what the individual works permit. -+When the Document is included in an aggregate, this License does not -+apply to the other works in the aggregate which are not themselves -+derivative works of the Document. -+ -+If the Cover Text requirement of section 3 is applicable to these -+copies of the Document, then if the Document is less than one half of -+the entire aggregate, the Document's Cover Texts may be placed on -+covers that bracket the Document within the aggregate, or the -+electronic equivalent of covers if the Document is in electronic form. -+Otherwise they must appear on printed covers that bracket the whole -+aggregate. -+ -+@item -+TRANSLATION -+ -+Translation is considered a kind of modification, so you may -+distribute translations of the Document under the terms of section 4. -+Replacing Invariant Sections with translations requires special -+permission from their copyright holders, but you may include -+translations of some or all Invariant Sections in addition to the -+original versions of these Invariant Sections. You may include a -+translation of this License, and all the license notices in the -+Document, and any Warranty Disclaimers, provided that you also include -+the original English version of this License and the original versions -+of those notices and disclaimers. In case of a disagreement between -+the translation and the original version of this License or a notice -+or disclaimer, the original version will prevail. -+ -+If a section in the Document is Entitled ``Acknowledgements'', -+``Dedications'', or ``History'', the requirement (section 4) to Preserve -+its Title (section 1) will typically require changing the actual -+title. -+ -+@item -+TERMINATION -+ -+You may not copy, modify, sublicense, or distribute the Document except -+as expressly provided for under this License. Any other attempt to -+copy, modify, sublicense or distribute the Document is void, and will -+automatically terminate your rights under this License. However, -+parties who have received copies, or rights, from you under this -+License will not have their licenses terminated so long as such -+parties remain in full compliance. -+ -+@item -+FUTURE REVISIONS OF THIS LICENSE -+ -+The Free Software Foundation may publish new, revised versions -+of the GNU Free Documentation License from time to time. Such new -+versions will be similar in spirit to the present version, but may -+differ in detail to address new problems or concerns. See -+@uref{http://www.gnu.org/copyleft/%7D. -+ -+Each version of the License is given a distinguishing version number. -+If the Document specifies that a particular numbered version of this -+License ``or any later version'' applies to it, you have the option of -+following the terms and conditions either of that specified version or -+of any later version that has been published (not as a draft) by the -+Free Software Foundation. If the Document does not specify a version -+number of this License, you may choose any version ever published (not -+as a draft) by the Free Software Foundation. -+@end enumerate -+ -+@page -+@appendixsubsec ADDENDUM: How to use this License for your documents -+ -+To use this License in a document you have written, include a copy of -+the License in the document and put the following copyright and -+license notices just after the title page: -+ -+@smallexample -+@group -+ Copyright (C) @var{year} @var{your name}. -+ Permission is granted to copy, distribute and/or modify this document -+ under the terms of the GNU Free Documentation License, Version 1.2 -+ or any later version published by the Free Software Foundation; -+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover -+ Texts. A copy of the license is included in the section entitled ``GNU -+ Free Documentation License''. -+@end group -+@end smallexample -+ -+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -+replace the ``with...Texts.'' line with this: -+ -+@smallexample -+@group -+ with the Invariant Sections being @var{list their titles}, with -+ the Front-Cover Texts being @var{list}, and with the Back-Cover Texts -+ being @var{list}. -+@end group -+@end smallexample -+ -+If you have Invariant Sections without Cover Texts, or some other -+combination of the three, merge those two alternatives to suit the -+situation. -+ -+If your document contains nontrivial examples of program code, we -+recommend releasing these examples in parallel under your choice of -+free software license, such as the GNU General Public License, -+to permit their use in free software. -+ -+@c Local Variables: -+@c ispell-local-pdict: "ispell-dict" -+@c End: -+ -diff -Nur grub-0.97/docs/grub.8 grub-0.97-patched/docs/grub.8 ---- grub-0.97/docs/grub.8 2005-05-08 04:48:56.000000000 +0200 -+++ grub-0.97-patched/docs/grub.8 2012-11-11 17:07:12.715729211 +0100 -@@ -1,5 +1,5 @@ - ." DO NOT MODIFY THIS FILE! It was generated by help2man 1.23. --.TH GRUB "8" "May 2005" "grub (GNU GRUB 0.97)" FSF -+.TH GRUB "8" "June 2006" "grub (GNU GRUB 0.97)" FSF - .SH NAME - grub - the grub shell - .SH SYNOPSIS -diff -Nur grub-0.97/docs/grub.8.additions grub-0.97-patched/docs/grub.8.additions ---- grub-0.97/docs/grub.8.additions 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/docs/grub.8.additions 2012-11-11 17:07:12.702728798 +0100 -@@ -0,0 +1,3 @@ -+[SEE ALSO] -+.BR update-grub (8), -+.BR grub-install (8). -diff -Nur grub-0.97/docs/grub-install.8 grub-0.97-patched/docs/grub-install.8 ---- grub-0.97/docs/grub-install.8 2005-05-08 04:48:56.000000000 +0200 -+++ grub-0.97-patched/docs/grub-install.8 2012-11-11 17:07:12.713729149 +0100 -@@ -1,5 +1,5 @@ - ." DO NOT MODIFY THIS FILE! It was generated by help2man 1.23. --.TH GRUB-INSTALL "8" "May 2005" "grub-install (GNU GRUB 0.97)" FSF -+.TH GRUB-INSTALL "8" "June 2006" "grub-install (GNU GRUB 0.97)" FSF - .SH NAME - grub-install - install GRUB on your drive - .SH SYNOPSIS -diff -Nur grub-0.97/docs/grub-install.8.additions grub-0.97-patched/docs/grub-install.8.additions ---- grub-0.97/docs/grub-install.8.additions 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/docs/grub-install.8.additions 2012-11-11 17:07:12.703728829 +0100 -@@ -0,0 +1,3 @@ -+[SEE ALSO] -+.BR grub (8), -+.BR update-grub (8). -diff -Nur grub-0.97/docs/grub-md5-crypt.8 grub-0.97-patched/docs/grub-md5-crypt.8 ---- grub-0.97/docs/grub-md5-crypt.8 2005-05-08 04:48:56.000000000 +0200 -+++ grub-0.97-patched/docs/grub-md5-crypt.8 2012-11-11 17:07:12.713729149 +0100 -@@ -1,5 +1,5 @@ - ." DO NOT MODIFY THIS FILE! It was generated by help2man 1.23. --.TH GRUB-MD5-CRYPT "8" "May 2005" "grub-md5-crypt (GNU GRUB )" FSF -+.TH GRUB-MD5-CRYPT "8" "June 2006" "grub-md5-crypt (GNU GRUB )" FSF - .SH NAME - grub-md5-crypt - Encrypt a password in MD5 format - .SH SYNOPSIS -diff -Nur grub-0.97/docs/grub-terminfo.8 grub-0.97-patched/docs/grub-terminfo.8 ---- grub-0.97/docs/grub-terminfo.8 2005-05-08 04:48:56.000000000 +0200 -+++ grub-0.97-patched/docs/grub-terminfo.8 2012-11-11 17:07:12.714729180 +0100 -@@ -1,5 +1,5 @@ - ." DO NOT MODIFY THIS FILE! It was generated by help2man 1.23. --.TH GRUB-TERMINFO "8" "May 2005" "grub-terminfo (GNU GRUB 0.97)" FSF -+.TH GRUB-TERMINFO "8" "June 2006" "grub-terminfo (GNU GRUB 0.97)" FSF - .SH NAME - grub-terminfo - Generate a terminfo command from a terminfo name - .SH SYNOPSIS -diff -Nur grub-0.97/docs/grub.texi grub-0.97-patched/docs/grub.texi ---- grub-0.97/docs/grub.texi 2005-05-08 04:59:59.000000000 +0200 -+++ grub-0.97-patched/docs/grub.texi 2012-11-11 17:07:12.717729276 +0100 -@@ -2,22 +2,41 @@ - @c -*-texinfo-*- - @c %**start of header - @setfilename grub.info --@settitle GRUB Manual --@c %**end of header -- - @include version.texi -- -+@settitle GNU GRUB Manual @value{VERSION} - @c Unify all our little indices for now. - @syncodeindex fn cp - @syncodeindex vr cp - @syncodeindex ky cp - @syncodeindex pg cp - @syncodeindex tp cp -+@c %**end of header - - @footnotestyle separate - @paragraphindent 3 - @finalout - -+@copying -+This manual is for GNU GRUB (version @value{VERSION}, -+@value{UPDATED}). -+ -+Copyright @copyright{} 1999,2000,2001,2002,2004,2006 Free Software Foundation, Inc. -+ -+@quotation -+Permission is granted to copy, distribute and/or modify this document -+under the terms of the GNU Free Documentation License, Version 1.2 or -+any later version published by the Free Software Foundation; with no -+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,'' -+and with the Back-Cover Texts as in (a) below. A copy of the -+license is included in the section entitled ``GNU Free Documentation -+License.'' -+ -+(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify -+this GNU Manual, like GNU software. Copies published by the Free -+Software Foundation raise funds for GNU development.'' -+@end quotation -+@end copying -+ - @dircategory Kernel - @direntry - * GRUB: (grub). The GRand Unified Bootloader -@@ -34,53 +53,16 @@ - - @setchapternewpage odd - --@ifinfo --Copyright @copyright{} 1999,2000,2001,2002,2004 Free Software Foundation, Inc. -- --Permission is granted to make and distribute verbatim copies of --this manual provided the copyright notice and this permission notice --are preserved on all copies. -- --@ignore --Permission is granted to process this file through TeX and print the --results, provided the printed document carries a copying permission --notice identical to this one except for the removal of this paragraph --(this paragraph not being relevant to the printed manual). -- --@end ignore -- --Permission is granted to copy and distribute modified versions of this --manual under the conditions for verbatim copying, provided also that --the entire resulting derived work is distributed under the terms of a --permission notice identical to this one. -- --Permission is granted to copy and distribute translations of this manual --into another language, under the above conditions for modified versions. --@end ifinfo -- - @titlepage - @sp 10 --@title the GRUB manual -+@title the GNU GRUB manual - @subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}. - @author Gordon Matzigkeit - @author Yoshinori K. Okuji - @c The following two commands start the copyright page. - @page - @vskip 0pt plus 1filll --Copyright @copyright{} 1999,2000,2001,2002,2004 Free Software Foundation, Inc. -- --Permission is granted to make and distribute verbatim copies of --this manual provided the copyright notice and this permission notice --are preserved on all copies. --Permission is granted to copy and distribute modified versions of this --manual under the conditions for verbatim copying, provided that the entire --resulting derived work is distributed under the terms of a permission --notice identical to this one. -- --Permission is granted to copy and distribute translations of this manual --into another language, under the above conditions for modified versions, --except that this permission notice may be stated in a translation approved --by Free Software Foundation. -+@insertcopying - @end titlepage - - @c Output the table of contents at the beginning. -@@ -91,12 +73,14 @@ - - @ifnottex - @node Top --@top GRUB manual -+@top GNU GRUB manual - - This is the documentation of GNU GRUB, the GRand Unified Bootloader, - a flexible and powerful boot loader program for @sc{pc}s. - - This edition documents version @value{VERSION}. -+ -+@insertcopying - @end ifnottex - - @menu -@@ -124,6 +108,7 @@ - * Reporting bugs:: Where you should send a bug report - * Future:: Some future plans on GRUB - * Internals:: Hacking GRUB -+* Copying This Manual:: Copying This Manual - * Index:: - @end menu - -@@ -3965,6 +3950,16 @@ - @include internals.texi - - -+@node Copying This Manual -+@appendix Copying This Manual -+ -+@menu -+* GNU Free Documentation License:: License for copying this manual. -+@end menu -+ -+@include fdl.texi -+ -+ - @node Index - @unnumbered Index - -diff -Nur grub-0.97/docs/help2man grub-0.97-patched/docs/help2man ---- grub-0.97/docs/help2man 2003-07-09 13:45:36.000000000 +0200 -+++ grub-0.97-patched/docs/help2man 2012-11-11 17:07:12.701728766 +0100 -@@ -455,7 +455,9 @@ - $include{$sect} .= <<EOT; - The full documentation for - .B $program --is maintained as a Texinfo manual. If the -+is maintained as a Texinfo manual in the -+.B grub-doc -+package. If the - .B info - and - .B $program -diff -Nur grub-0.97/docs/Makefile.am grub-0.97-patched/docs/Makefile.am ---- grub-0.97/docs/Makefile.am 2003-07-09 13:45:35.000000000 +0200 -+++ grub-0.97-patched/docs/Makefile.am 2012-11-11 17:07:12.711729085 +0100 -@@ -1,5 +1,5 @@ - info_TEXINFOS = grub.texi multiboot.texi --grub_TEXINFOS = internals.texi -+grub_TEXINFOS = internals.texi fdl.texi - EXAMPLES = boot.S kernel.c multiboot.h - multiboot_TEXINFOS = boot.S.texi kernel.c.texi multiboot.h.texi - man_MANS = grub.8 mbchk.1 grub-install.8 grub-md5-crypt.8 grub-terminfo.8 -@@ -37,14 +37,14 @@ - $(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@ - - if MAINTAINER_MODE --$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN) -+$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN) $(srcdir)/grub.8.additions - $(PERL) $(srcdir)/$(HELP2MAN) --name="the grub shell" \ -- --section=8 --output=$@ $< -+ --section=8 --include=$@.additions --output=$@ $< - --$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN) -+$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN) $(srcdir)/grub-install.8.additions - chmod 755 $< - $(PERL) $(srcdir)/$(HELP2MAN) --name="install GRUB on your drive" \ -- --section=8 --output=$@ $< -+ --section=8 --include=$@.additions --output=$@ $< - - $(srcdir)/mbchk.1: ../util/mbchk $(srcdir)/$(HELP2MAN) - $(PERL) $(srcdir)/$(HELP2MAN) \ -diff -Nur grub-0.97/docs/mbchk.1 grub-0.97-patched/docs/mbchk.1 ---- grub-0.97/docs/mbchk.1 2005-05-08 04:48:56.000000000 +0200 -+++ grub-0.97-patched/docs/mbchk.1 2012-11-11 17:07:12.717729276 +0100 -@@ -1,5 +1,5 @@ - ." DO NOT MODIFY THIS FILE! It was generated by help2man 1.23. --.TH MBCHK "1" "May 2005" "mbchk (GNU GRUB 0.97)" FSF -+.TH MBCHK "1" "June 2006" "mbchk (GNU GRUB 0.97)" FSF - .SH NAME - mbchk - check the format of a Multiboot kernel - .SH SYNOPSIS -diff -Nur grub-0.97/docs/menu.lst grub-0.97-patched/docs/menu.lst ---- grub-0.97/docs/menu.lst 2004-05-11 14:11:17.000000000 +0200 -+++ grub-0.97-patched/docs/menu.lst 2012-11-11 17:07:07.225553829 +0100 -@@ -11,6 +11,9 @@ - # Fallback to the second entry. - fallback 1 - -+# Splash image to show behind grub. -+splashimage=(hd0,0)/boot/grub/splash.xpm.gz -+ - # For booting GNU/Hurd - title GNU/Hurd - root (hd0,0) -@@ -23,6 +26,11 @@ - kernel /vmlinuz root=/dev/hdb1 - #initrd /initrd.img - -+# For booting Gentoo with the static rescue shell -+title Gentoo (rescue shell) -+root (hd1,0) -+kernel /vmlinuz root=/dev/hdb1 init=/bin/bb -+ - # For booting GNU/kFreeBSD - title GNU/kFreeBSD - root (hd0,2,a) -diff -Nur grub-0.97/docs/menu.lst.orig grub-0.97-patched/docs/menu.lst.orig ---- grub-0.97/docs/menu.lst.orig 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/docs/menu.lst.orig 2004-05-11 14:11:17.000000000 +0200 -@@ -0,0 +1,82 @@ -+# -+# Sample boot menu configuration file -+# -+ -+# Boot automatically after 30 secs. -+timeout 30 -+ -+# By default, boot the first entry. -+default 0 -+ -+# Fallback to the second entry. -+fallback 1 -+ -+# For booting GNU/Hurd -+title GNU/Hurd -+root (hd0,0) -+kernel /boot/gnumach.gz root=hd0s1 -+module /boot/serverboot.gz -+ -+# For booting GNU/Linux -+title GNU/Linux -+root (hd1,0) -+kernel /vmlinuz root=/dev/hdb1 -+#initrd /initrd.img -+ -+# For booting GNU/kFreeBSD -+title GNU/kFreeBSD -+root (hd0,2,a) -+kernel /boot/loader.gz -+ -+# For booting GNU/kNetBSD -+title GNU/kNetBSD -+root (hd0,2,a) -+kernel --type=netbsd /boot/knetbsd.gz -+ -+# For booting Mach (getting kernel from floppy) -+title Utah Mach4 multiboot -+root (hd0,2) -+pause Insert the diskette now!! -+kernel (fd0)/boot/kernel root=hd0s3 -+module (fd0)/boot/bootstrap -+ -+# For booting FreeBSD -+title FreeBSD -+root (hd0,2,a) -+kernel /boot/loader -+ -+# For booting NetBSD -+title NetBSD -+root (hd0,2,a) -+kernel --type=netbsd /netbsd -+ -+# For booting OpenBSD -+title OpenBSD -+root (hd0,2,a) -+kernel --type=netbsd /bsd -+ -+# For booting OS/2 -+title OS/2 -+root (hd0,1) -+makeactive -+# chainload OS/2 bootloader from the first sector -+chainloader +1 -+# This is similar to "chainload", but loads a specific file -+#chainloader /boot/chain.os2 -+ -+# For booting Windows NT or Windows95 -+title Windows NT / Windows 95 boot menu -+rootnoverify (hd0,0) -+makeactive -+chainloader +1 -+# For loading DOS if Windows NT is installed -+# chainload /bootsect.dos -+ -+# For installing GRUB into the hard disk -+title Install GRUB into the hard disk -+root (hd0,0) -+setup (hd0) -+ -+# Change the colors. -+title Change the colors -+color light-green/brown blink-red/blue -diff -Nur grub-0.97/docs/multiboot.texi grub-0.97-patched/docs/multiboot.texi ---- grub-0.97/docs/multiboot.texi 2003-07-09 13:45:36.000000000 +0200 -+++ grub-0.97-patched/docs/multiboot.texi 2012-11-11 17:07:12.718729309 +0100 -@@ -1,32 +1,28 @@ - \input texinfo @c -*-texinfo-*- --@c -*-texinfo-*- - @c %**start of header - @setfilename multiboot.info --@settitle Multiboot Specification --@c %**end of header -- -+@set VERSION 0.6.95 -+@settitle Multiboot Specification version @value{VERSION} - @c Unify all our little indices for now. - @syncodeindex fn cp - @syncodeindex vr cp - @syncodeindex ky cp - @syncodeindex pg cp - @syncodeindex tp cp -+@c %**end of header - - @footnotestyle separate - @paragraphindent 3 - @finalout - -+@copying -+Copyright @copyright{} 1995,96 Bryan Ford <baford@@cs.utah.edu> - --@dircategory Kernel --@direntry --* Multiboot Specification: (multiboot). Multiboot Specification. --@end direntry -+Copyright @copyright{} 1995,96 Erich Stefan Boleyn <erich@@uruk.org> - --@ifinfo --Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu> --Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org> --Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -+Copyright @copyright{} 1999,2000,2001,2002,2005,2006 Free Software Foundation, Inc. - -+@quotation - Permission is granted to make and distribute verbatim copies of - this manual provided the copyright notice and this permission notice - are preserved on all copies. -@@ -36,7 +32,6 @@ - results, provided the printed document carries a copying permission - notice identical to this one except for the removal of this paragraph - (this paragraph not being relevant to the printed manual). -- - @end ignore - - Permission is granted to copy and distribute modified versions of this -@@ -45,31 +40,23 @@ - permission notice identical to this one. - - Permission is granted to copy and distribute translations of this manual --into another language, under the above conditions for modified versions. --@end ifinfo -+into another language, under the above conditions for modified -+versions. -+@end quotation -+@end copying -+ -+@dircategory Kernel -+@direntry -+* Multiboot Specification: (multiboot). Multiboot Specification. -+@end direntry - - @titlepage - @sp 10 --@title The Multiboot Specification -+@title The Multiboot Specification version @value{VERSION} - @author Yoshinori K. Okuji, Bryan Ford, Erich Stefan Boleyn, Kunihiro Ishiguro - @page -- - @vskip 0pt plus 1filll --Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu> --Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org> --Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -- --Permission is granted to make and distribute verbatim copies of --this manual provided the copyright notice and this permission notice --are preserved on all copies. -- --Permission is granted to copy and distribute modified versions of this --manual under the conditions for verbatim copying, provided also that --the entire resulting derived work is distributed under the terms of a --permission notice identical to this one. -- --Permission is granted to copy and distribute translations of this manual --into another language, under the above conditions for modified versions. -+@insertcopying - @end titlepage - - @finalout -@@ -80,7 +67,9 @@ - @top Multiboot Specification - - This file documents Multiboot Specification, the proposal for the boot --sequence standard. This edition documents version 0.6.93. -+sequence standard. This edition documents version @value{VERSION}. -+ -+@insertcopying - @end ifnottex - - @menu -@@ -426,7 +415,7 @@ - kernel. - - If bit 16 in the @samp{flags} word is set, then the fields at offsets --8-24 in the Multiboot header are valid, and the boot loader should use -+12-28 in the Multiboot header are valid, and the boot loader should use - them instead of the fields in the actual executable header to calculate - where to load the OS image. This information does not need to be - provided if the kernel image is in @sc{elf} format, but it @emph{must} -@@ -677,7 +666,7 @@ - @example - @group - +-------+-------+-------+-------+ --| drive | part1 | part2 | part3 | -+| part3 | part2 | part1 | drive | - +-------+-------+-------+-------+ - @end group - @end example -@@ -1197,6 +1186,17 @@ - @item - The maintainer changes to the GNU GRUB maintainer team - @email{bug-grub@@gnu.org}, from Bryan Ford and Erich Stefan Boleyn. -+ -+@item -+The byte order of the @samp{boot_device} in Multiboot information is -+reversed. This was a mistake. -+ -+@item -+The offset of the address fields were wrong. -+ -+@item -+The format is adapted to a newer Texinfo, and the version number is -+specified more explicitly in the title. - @end itemize - - @item 0.6 -diff -Nur grub-0.97/grub/asmstub.c grub-0.97-patched/grub/asmstub.c ---- grub-0.97/grub/asmstub.c 2005-02-16 21:45:14.000000000 +0100 -+++ grub-0.97-patched/grub/asmstub.c 2012-11-11 17:07:12.719729342 +0100 -@@ -42,6 +42,7 @@ - #include <sys/time.h> - #include <termios.h> - #include <signal.h> -+#include <sys/mman.h> - - #ifdef __linux__ - # include <sys/ioctl.h> /* ioctl */ -@@ -55,6 +56,10 @@ - # endif /* ! BLKFLSBUF */ - #endif /* __linux__ */ - -+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) -+# include <sys/sysctl.h> -+#endif -+ - /* We want to prevent any circularararity in our stubs, as well as - libc name clashes. */ - #define WITHOUT_LIBC_STUBS 1 -@@ -79,7 +84,7 @@ - struct apm_info apm_bios_info; - - /* Emulation requirements. */ --char *grub_scratch_mem = 0; -+void *grub_scratch_mem = 0; - - struct geometry *disks = 0; - -@@ -103,14 +108,62 @@ - static unsigned int serial_speed; - #endif /* SIMULATE_SLOWNESS_OF_SERIAL */ - -+/* This allocates page-aligned storage of the specified size, which must be -+ * a multiple of the page size as determined by calling sysconf(_SC_PAGESIZE) -+ */ -+#ifdef __linux__ -+static void * -+grub_mmap_alloc(size_t len) -+{ -+ int mmap_flags = MAP_ANONYMOUS|MAP_PRIVATE; -+ -+#ifdef MAP_32BIT -+ mmap_flags |= MAP_32BIT; -+#endif -+ /* Mark the simulated stack executable, as GCC uses stack trampolines -+ * to implement nested functions. */ -+ return mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC, mmap_flags, -1, 0); -+} -+#else /* !defined(__linux__) */ -+static void * -+grub_mmap_alloc(size_t len) -+{ -+ int fd = 0, offset = 0, ret = 0; -+ void *pa = MAP_FAILED; -+ char template[] = "/tmp/grub_mmap_alloc_XXXXXX"; -+ int e; -+ -+ fd = mkstemp(template); -+ if (fd < 0) -+ return pa; -+ -+ unlink(template); -+ -+ ret = ftruncate(fd, len); -+ if (ret < 0) -+ return pa; -+ -+ /* Mark the simulated stack executable, as GCC uses stack trampolines -+ * to implement nested functions. */ -+ pa = mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC, -+ MAP_PRIVATE, fd, offset); -+ -+ e = errno; -+ close(fd); -+ errno = e; -+ return pa; -+} -+#endif /* defined(__linux__) */ -+ - /* The main entry point into this mess. */ - int - grub_stage2 (void) - { - /* These need to be static, because they survive our stack transitions. */ - static int status = 0; -- static char *realstack; -- char *scratch, *simstack; -+ static void *realstack; -+ void *simstack_alloc_base, *simstack; -+ size_t simstack_size, page_size; - int i; - - auto void doit (void); -@@ -142,9 +195,35 @@ - } - - assert (grub_scratch_mem == 0); -- scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15); -- assert (scratch); -- grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4); -+ -+ /* Allocate enough pages for 0x100000 + EXTENDED_SIZE + 15, and -+ * make sure the memory is aligned to a multiple of the system's -+ * page size */ -+ page_size = sysconf (_SC_PAGESIZE); -+ simstack_size = ( 0x100000 + EXTENDED_MEMSIZE + 15); -+ if (simstack_size % page_size) -+ { -+ /* If we're not on a page_size boundary, round up to the next one */ -+ simstack_size &= ~(page_size-1); -+ simstack_size += page_size; -+ } -+ -+ /* Add one for a PROT_NONE boundary page at each end. */ -+ simstack_size += 2 * page_size; -+ -+ simstack_alloc_base = grub_mmap_alloc(simstack_size); -+ assert (simstack_alloc_base != MAP_FAILED); -+ -+ /* mark pages above and below our simstack area as innaccessable. -+ * If the implementation we're using doesn't support that, then the -+ * new protection modes are undefined. It's safe to just ignore -+ * them, though. It'd be nice if we knew that we'd get a SEGV for -+ * touching the area, but that's all. it'd be nice to have. */ -+ mprotect (simstack_alloc_base, page_size, PROT_NONE); -+ mprotect ((void *)((unsigned long)simstack_alloc_base + -+ simstack_size - page_size), page_size, PROT_NONE); -+ -+ grub_scratch_mem = (void *)((unsigned long)simstack_alloc_base + page_size); - - /* FIXME: simulate the memory holes using mprot, if available. */ - -@@ -217,7 +296,7 @@ - device_map = 0; - free (disks); - disks = 0; -- free (scratch); -+ munmap(simstack_alloc_base, simstack_size); - grub_scratch_mem = 0; - - if (serial_device) -@@ -777,7 +856,39 @@ - - /* Open read/write, or read-only if that failed. */ - if (! read_only) -- disks[drive].flags = open (devname, O_RDWR); -+ { -+/* By default, kernel of FreeBSD does not allow overwriting MBR */ -+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) -+#define GEOM_SYSCTL "kern.geom.debugflags" -+ int old_flags, flags; -+ size_t sizeof_int = sizeof (int); -+ -+ if (sysctlbyname (GEOM_SYSCTL, &old_flags, &sizeof_int, NULL, 0) != 0) -+ grub_printf ("failed to get " GEOM_SYSCTL "sysctl: %s\n", strerror (errno)); -+ -+ if ((old_flags & 0x10) == 0) -+ { -+ /* "allow foot shooting", see geom(4) */ -+ flags = old_flags | 0x10; -+ -+ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &flags, sizeof (int)) != 0) -+ { -+ flags = old_flags; -+ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno)); -+ } -+ } -+ else -+ flags = old_flags; -+#endif -+ disks[drive].flags = open (devname, O_RDWR); -+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) -+ if (flags != old_flags) -+ { -+ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &old_flags, sizeof (int)) != 0) -+ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno)); -+ } -+#endif -+ } - - if (disks[drive].flags == -1) - { -@@ -926,7 +1037,7 @@ - - int - biosdisk (int subfunc, int drive, struct geometry *geometry, -- int sector, int nsec, int segment) -+ unsigned int sector, int nsec, int segment) - { - char *buf; - int fd = geometry->flags; -diff -Nur grub-0.97/grub/asmstub.c.orig grub-0.97-patched/grub/asmstub.c.orig ---- grub-0.97/grub/asmstub.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/grub/asmstub.c.orig 2005-02-16 21:45:14.000000000 +0100 -@@ -0,0 +1,1275 @@ -+/* asmstub.c - a version of shared_src/asm.S that works under Unix */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 1999,2000,2001,2002,2004 Free Software Foundation, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * 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, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+/* Try to use glibc's transparant LFS support. */ -+#define _LARGEFILE_SOURCE 1 -+/* lseek becomes synonymous with lseek64. */ -+#define _FILE_OFFSET_BITS 64 -+ -+/* Simulator entry point. */ -+int grub_stage2 (void); -+ -+#include <stdlib.h> -+#include <string.h> -+#include <ctype.h> -+#include <assert.h> -+#include <stdio.h> -+#include <sys/types.h> -+#include <sys/stat.h> -+#include <fcntl.h> -+#include <time.h> -+#include <errno.h> -+#include <string.h> -+#include <unistd.h> -+#include <setjmp.h> -+#include <sys/time.h> -+#include <termios.h> -+#include <signal.h> -+ -+#ifdef __linux__ -+# include <sys/ioctl.h> /* ioctl */ -+# if !defined(__GLIBC__) || \ -+ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) -+/* Maybe libc doesn't have large file support. */ -+# include <linux/unistd.h> /* _llseek */ -+# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */ -+# ifndef BLKFLSBUF -+# define BLKFLSBUF _IO (0x12,97) /* flush buffer cache */ -+# endif /* ! BLKFLSBUF */ -+#endif /* __linux__ */ -+ -+/* We want to prevent any circularararity in our stubs, as well as -+ libc name clashes. */ -+#define WITHOUT_LIBC_STUBS 1 -+#include <shared.h> -+#include <device.h> -+#include <serial.h> -+#include <term.h> -+ -+/* Simulated memory sizes. */ -+#define EXTENDED_MEMSIZE (3 * 1024 * 1024) /* 3MB */ -+#define CONVENTIONAL_MEMSIZE (640 * 1024) /* 640kB */ -+ -+unsigned long install_partition = 0x20000; -+unsigned long boot_drive = 0; -+int saved_entryno = 0; -+char version_string[] = VERSION; -+char config_file[128] = "/boot/grub/menu.lst"; /* FIXME: arbitrary */ -+unsigned long linux_text_len = 0; -+char *linux_data_tmp_addr = 0; -+char *linux_data_real_addr = 0; -+unsigned short io_map[IO_MAP_SIZE]; -+struct apm_info apm_bios_info; -+ -+/* Emulation requirements. */ -+char *grub_scratch_mem = 0; -+ -+struct geometry *disks = 0; -+ -+/* The map between BIOS drives and UNIX device file names. */ -+char **device_map = 0; -+ -+/* The jump buffer for exiting correctly. */ -+static jmp_buf env_for_exit; -+ -+/* The current color for console. */ -+int console_current_color = A_NORMAL; -+ -+/* The file descriptor for a serial device. */ -+static int serial_fd = -1; -+ -+/* The file name of a serial device. */ -+static char *serial_device = 0; -+ -+#ifdef SIMULATE_SLOWNESS_OF_SERIAL -+/* The speed of a serial device. */ -+static unsigned int serial_speed; -+#endif /* SIMULATE_SLOWNESS_OF_SERIAL */ -+ -+/* The main entry point into this mess. */ -+int -+grub_stage2 (void) -+{ -+ /* These need to be static, because they survive our stack transitions. */ -+ static int status = 0; -+ static char *realstack; -+ char *scratch, *simstack; -+ int i; -+ -+ auto void doit (void); -+ -+ /* We need a nested function so that we get a clean stack frame, -+ regardless of how the code is optimized. */ -+ void doit (void) -+ { -+ /* Make sure our stack lives in the simulated memory area. */ -+ asm volatile ("movl %%esp, %0\n\tmovl %1, %%esp\n" -+ : "=&r" (realstack) : "r" (simstack)); -+ -+ /* Do a setjmp here for the stop command. */ -+ if (! setjmp (env_for_exit)) -+ { -+ /* Actually enter the generic stage2 code. */ -+ status = 0; -+ init_bios_info (); -+ } -+ else -+ { -+ /* If ERRNUM is non-zero, then set STATUS to non-zero. */ -+ if (errnum) -+ status = 1; -+ } -+ -+ /* Replace our stack before we use any local variables. */ -+ asm volatile ("movl %0, %%esp\n" : : "r" (realstack)); -+ } -+ -+ assert (grub_scratch_mem == 0); -+ scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15); -+ assert (scratch); -+ grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4); -+ -+ /* FIXME: simulate the memory holes using mprot, if available. */ -+ -+ assert (disks == 0); -+ disks = malloc (NUM_DISKS * sizeof (*disks)); -+ assert (disks); -+ /* Initialize DISKS. */ -+ for (i = 0; i < NUM_DISKS; i++) -+ disks[i].flags = -1; -+ -+ if (! init_device_map (&device_map, device_map_file, floppy_disks)) -+ return 1; -+ -+ /* Check some invariants. */ -+ assert ((SCRATCHSEG << 4) == SCRATCHADDR); -+ assert ((BUFFERSEG << 4) == BUFFERADDR); -+ assert (BUFFERADDR + BUFFERLEN == SCRATCHADDR); -+ assert (FSYS_BUF % 16 == 0); -+ assert (FSYS_BUF + FSYS_BUFLEN == BUFFERADDR); -+ -+#ifdef HAVE_LIBCURSES -+ /* Get into char-at-a-time mode. */ -+ if (use_curses) -+ { -+ initscr (); -+ cbreak (); -+ noecho (); -+ nonl (); -+ scrollok (stdscr, TRUE); -+ keypad (stdscr, TRUE); -+ wtimeout (stdscr, 100); -+ signal (SIGWINCH, SIG_IGN); -+ } -+#endif -+ -+ /* Make sure that actual writing is done. */ -+ sync (); -+ -+ /* Set our stack, and go for it. */ -+ simstack = (char *) PROTSTACKINIT; -+ doit (); -+ -+ /* I don't know if this is necessary really. */ -+ sync (); -+ -+#ifdef HAVE_LIBCURSES -+ if (use_curses) -+ endwin (); -+#endif -+ -+ /* Close off the file descriptors we used. */ -+ for (i = 0; i < NUM_DISKS; i ++) -+ if (disks[i].flags != -1) -+ { -+#ifdef __linux__ -+ /* In Linux, invalidate the buffer cache. In other OSes, reboot -+ is one of the solutions... */ -+ ioctl (disks[i].flags, BLKFLSBUF, 0); -+#else -+# warning "In your operating system, the buffer cache will not be flushed." -+#endif -+ close (disks[i].flags); -+ } -+ -+ if (serial_fd >= 0) -+ close (serial_fd); -+ -+ /* Release memory. */ -+ restore_device_map (device_map); -+ device_map = 0; -+ free (disks); -+ disks = 0; -+ free (scratch); -+ grub_scratch_mem = 0; -+ -+ if (serial_device) -+ free (serial_device); -+ serial_device = 0; -+ -+ /* Ahh... at last we're ready to return to caller. */ -+ return status; -+} -+ -+/* Assign DRIVE to a device name DEVICE. */ -+void -+assign_device_name (int drive, const char *device) -+{ -+ /* If DRIVE is already assigned, free it. */ -+ if (device_map[drive]) -+ free (device_map[drive]); -+ -+ /* If the old one is already opened, close it. */ -+ if (disks[drive].flags != -1) -+ { -+ close (disks[drive].flags); -+ disks[drive].flags = -1; -+ } -+ -+ /* Assign DRIVE to DEVICE. */ -+ if (! device) -+ device_map[drive] = 0; -+ else -+ device_map[drive] = strdup (device); -+} -+ -+void -+stop (void) -+{ -+#ifdef HAVE_LIBCURSES -+ if (use_curses) -+ endwin (); -+#endif -+ -+ /* Jump to doit. */ -+ longjmp (env_for_exit, 1); -+} -+ -+void -+grub_reboot (void) -+{ -+ stop (); -+} -+ -+void -+grub_halt (int no_apm) -+{ -+ stop (); -+} -+ -+/* calls for direct boot-loader chaining */ -+void -+chain_stage1 (unsigned long segment, unsigned long offset, -+ unsigned long part_table_addr) -+{ -+ stop (); -+} -+ -+ -+void -+chain_stage2 (unsigned long segment, unsigned long offset, int second_sector) -+{ -+ stop (); -+} -+ -+ -+/* do some funky stuff, then boot linux */ -+void -+linux_boot (void) -+{ -+ stop (); -+} -+ -+ -+/* For bzImage kernels. */ -+void -+big_linux_boot (void) -+{ -+ stop (); -+} -+ -+ -+/* booting a multiboot executable */ -+void -+multi_boot (int start, int mb_info) -+{ -+ stop (); -+} -+ -+/* sets it to linear or wired A20 operation */ -+void -+gateA20 (int linear) -+{ -+ /* Nothing to do in the simulator. */ -+} -+ -+/* Set up the int15 handler. */ -+void -+set_int15_handler (void) -+{ -+ /* Nothing to do in the simulator. */ -+} -+ -+/* Restore the original int15 handler. */ -+void -+unset_int15_handler (void) -+{ -+ /* Nothing to do in the simulator. */ -+} -+ -+/* The key map. */ -+unsigned short bios_key_map[KEY_MAP_SIZE + 1]; -+unsigned short ascii_key_map[KEY_MAP_SIZE + 1]; -+ -+/* Copy MAP to the drive map and set up the int13 handler. */ -+void -+set_int13_handler (unsigned short *map) -+{ -+ /* Nothing to do in the simulator. */ -+} -+ -+int -+get_code_end (void) -+{ -+ /* Just return a little area for simulation. */ -+ return BOOTSEC_LOCATION + (60 * 1024); -+} -+ -+ -+/* memory probe routines */ -+int -+get_memsize (int type) -+{ -+ if (! type) -+ return CONVENTIONAL_MEMSIZE >> 10; -+ else -+ return EXTENDED_MEMSIZE >> 10; -+} -+ -+ -+/* get_eisamemsize() : return packed EISA memory map, lower 16 bits is -+ * memory between 1M and 16M in 1K parts, upper 16 bits is -+ * memory above 16M in 64K parts. If error, return -1. -+ */ -+int -+get_eisamemsize (void) -+{ -+ return (EXTENDED_MEMSIZE >> 10); -+} -+ -+ -+#define MMAR_DESC_TYPE_AVAILABLE 1 /* available to OS */ -+#define MMAR_DESC_TYPE_RESERVED 2 /* not available */ -+#define MMAR_DESC_TYPE_ACPI_RECLAIM 3 /* usable by OS after reading ACPI */ -+#define MMAR_DESC_TYPE_ACPI_NVS 4 /* required to save between NVS sessions */ -+ -+#define MMAR_DESC_LENGTH 20 -+ -+/* Fetch the next entry in the memory map and return the continuation -+ value. DESC is a pointer to the descriptor buffer, and CONT is the -+ previous continuation value (0 to get the first entry in the -+ map). */ -+int -+get_mmap_entry (struct mmar_desc *desc, int cont) -+{ -+ /* Record the memory map statically. */ -+ static struct mmar_desc desc_table[] = -+ { -+ /* The conventional memory. */ -+ { -+ MMAR_DESC_LENGTH, -+ 0, -+ CONVENTIONAL_MEMSIZE, -+ MMAR_DESC_TYPE_AVAILABLE -+ }, -+ /* BIOS RAM and ROM (such as video memory). */ -+ { -+ MMAR_DESC_LENGTH, -+ CONVENTIONAL_MEMSIZE, -+ 0x100000 - CONVENTIONAL_MEMSIZE, -+ MMAR_DESC_TYPE_RESERVED -+ }, -+ /* The extended memory. */ -+ { -+ MMAR_DESC_LENGTH, -+ 0x100000, -+ EXTENDED_MEMSIZE, -+ MMAR_DESC_TYPE_AVAILABLE -+ } -+ }; -+ -+ int num = sizeof (desc_table) / sizeof (*desc_table); -+ -+ if (cont < 0 || cont >= num) -+ { -+ /* Should not happen. */ -+ desc->desc_len = 0; -+ } -+ else -+ { -+ /* Copy the entry. */ -+ *desc = desc_table[cont++]; -+ -+ /* If the next entry exists, return the index. */ -+ if (cont < num) -+ return cont; -+ } -+ -+ return 0; -+} -+ -+/* Track the int13 handler. */ -+void -+track_int13 (int drive) -+{ -+ /* Nothing to do in the simulator. */ -+} -+ -+/* Get the ROM configuration table. */ -+unsigned long -+get_rom_config_table (void) -+{ -+ return 0; -+} -+ -+/* Get APM BIOS information. */ -+void -+get_apm_info (void) -+{ -+ /* Nothing to do in the simulator. */ -+} -+ -+/* Get VBE controller information. */ -+int -+get_vbe_controller_info (struct vbe_controller *controller) -+{ -+ /* Always fails. */ -+ return 0; -+} -+ -+/* Get VBE mode information. */ -+int -+get_vbe_mode_info (int mode_number, struct vbe_mode *mode) -+{ -+ /* Always fails. */ -+ return 0; -+} -+ -+/* Set VBE mode. */ -+int -+set_vbe_mode (int mode_number) -+{ -+ /* Always fails. */ -+ return 0; -+} -+ -+/* low-level timing info */ -+int -+getrtsecs (void) -+{ -+ /* FIXME: exact value is not important, so just return time_t for now. */ -+ return time (0); -+} -+ -+int -+currticks (void) -+{ -+ struct timeval tv; -+ long csecs; -+ int ticks_per_csec, ticks_per_usec; -+ -+ /* Note: 18.2 ticks/sec. */ -+ -+ /* Get current time. */ -+ gettimeofday (&tv, 0); -+ -+ /* Compute centiseconds. */ -+ csecs = tv.tv_sec / 10; -+ -+ /* Ticks per centisecond. */ -+ ticks_per_csec = csecs * 182; -+ -+ /* Ticks per microsecond. */ -+ ticks_per_usec = (((tv.tv_sec - csecs * 10) * 1000000 + tv.tv_usec) -+ * 182 / 10000000); -+ -+ /* Sum them. */ -+ return ticks_per_csec + ticks_per_usec; -+} -+ -+/* displays an ASCII character. IBM displays will translate some -+ characters to special graphical ones */ -+void -+console_putchar (int c) -+{ -+ /* Curses doesn't have VGA fonts. */ -+ switch (c) -+ { -+ case DISP_UL: -+ c = ACS_ULCORNER; -+ break; -+ case DISP_UR: -+ c = ACS_URCORNER; -+ break; -+ case DISP_LL: -+ c = ACS_LLCORNER; -+ break; -+ case DISP_LR: -+ c = ACS_LRCORNER; -+ break; -+ case DISP_HORIZ: -+ c = ACS_HLINE; -+ break; -+ case DISP_VERT: -+ c = ACS_VLINE; -+ break; -+ case DISP_LEFT: -+ c = ACS_LARROW; -+ break; -+ case DISP_RIGHT: -+ c = ACS_RARROW; -+ break; -+ case DISP_UP: -+ c = ACS_UARROW; -+ break; -+ case DISP_DOWN: -+ c = ACS_DARROW; -+ break; -+ default: -+ break; -+ } -+ -+#ifdef HAVE_LIBCURSES -+ if (use_curses) -+ { -+ /* In ncurses, a newline is treated badly, so we emulate it in our -+ own way. */ -+ if (c == '\n') -+ { -+ int x, y; -+ -+ getyx (stdscr, y, x); -+ if (y + 1 == LINES) -+ scroll (stdscr); -+ else -+ move (y + 1, x); -+ } -+ else if (isprint (c)) -+ { -+ int x, y; -+ -+ getyx (stdscr, y, x); -+ if (x + 1 == COLS) -+ { -+ console_putchar ('\r'); -+ console_putchar ('\n'); -+ } -+ addch (c | console_current_color); -+ } -+ else -+ { -+ addch (c); -+ } -+ -+#ifdef REFRESH_IMMEDIATELY -+ refresh (); -+#endif -+ } -+ else -+#endif -+ { -+ /* CR is not used in Unix. */ -+ if (c != '\r') -+ putchar (c); -+ } -+} -+ -+/* The store for ungetch simulation. This is necessary, because -+ ncurses-1.9.9g is still used in the world and its ungetch is -+ completely broken. */ -+#ifdef HAVE_LIBCURSES -+static int save_char = ERR; -+#endif -+ -+static int -+console_translate_key (int c) -+{ -+ switch (c) -+ { -+ case KEY_LEFT: -+ return 2; -+ case KEY_RIGHT: -+ return 6; -+ case KEY_UP: -+ return 16; -+ case KEY_DOWN: -+ return 14; -+ case KEY_DC: -+ return 4; -+ case KEY_BACKSPACE: -+ return 8; -+ case KEY_HOME: -+ return 1; -+ case KEY_END: -+ return 5; -+ case KEY_PPAGE: -+ return 7; -+ case KEY_NPAGE: -+ return 3; -+ default: -+ break; -+ } -+ -+ return c; -+} -+ -+/* like 'getkey', but doesn't wait, returns -1 if nothing available */ -+int -+console_checkkey (void) -+{ -+#ifdef HAVE_LIBCURSES -+ if (use_curses) -+ { -+ int c; -+ -+ /* Check for SAVE_CHAR. This should not be true, because this -+ means checkkey is called twice continuously. */ -+ if (save_char != ERR) -+ return save_char; -+ -+ c = getch (); -+ /* If C is not ERR, then put it back in the input queue. */ -+ if (c != ERR) -+ save_char = c; -+ return console_translate_key (c); -+ } -+#endif -+ -+ /* Just pretend they hit the space bar, then read the real key when -+ they call getkey. */ -+ return ' '; -+} -+ -+/* returns packed BIOS/ASCII code */ -+int -+console_getkey (void) -+{ -+ int c; -+ -+#ifdef HAVE_LIBCURSES -+ if (use_curses) -+ { -+ /* If checkkey has already got a character, then return it. */ -+ if (save_char != ERR) -+ { -+ c = save_char; -+ save_char = ERR; -+ return console_translate_key (c); -+ } -+ -+ wtimeout (stdscr, -1); -+ c = getch (); -+ wtimeout (stdscr, 100); -+ } -+ else -+#endif -+ c = getchar (); -+ -+ /* Quit if we get EOF. */ -+ if (c == -1) -+ stop (); -+ -+ return console_translate_key (c); -+} -+ -+/* returns packed values, LSB+1 is x, LSB is y */ -+int -+console_getxy (void) -+{ -+ int y, x; -+#ifdef HAVE_LIBCURSES -+ if (use_curses) -+ getyx (stdscr, y, x); -+ else -+#endif -+ y = x = 0; -+ return (x << 8) | (y & 0xff); -+} -+ -+void -+console_gotoxy (int x, int y) -+{ -+#ifdef HAVE_LIBCURSES -+ if (use_curses) -+ move (y, x); -+#endif -+} -+ -+/* low-level character I/O */ -+void -+console_cls (void) -+{ -+#ifdef HAVE_LIBCURSES -+ if (use_curses) -+ clear (); -+#endif -+} -+ -+void -+console_setcolorstate (color_state state) -+{ -+ console_current_color = -+ (state == COLOR_STATE_HIGHLIGHT) ? A_REVERSE : A_NORMAL; -+} -+ -+void -+console_setcolor (int normal_color, int highlight_color) -+{ -+ /* Nothing to do. */ -+} -+ -+int -+console_setcursor (int on) -+{ -+ return 1; -+} -+ -+/* Low-level disk I/O. Our stubbed version just returns a file -+ descriptor, not the actual geometry. */ -+int -+get_diskinfo (int drive, struct geometry *geometry) -+{ -+ /* FIXME: this function is truly horrid. We try opening the device, -+ then severely abuse the GEOMETRY->flags field to pass a file -+ descriptor to biosdisk. Thank God nobody's looking at this comment, -+ or my reputation would be ruined. --Gord */ -+ -+ /* See if we have a cached device. */ -+ if (disks[drive].flags == -1) -+ { -+ /* The unpartitioned device name: /dev/XdX */ -+ char *devname = device_map[drive]; -+ char buf[512]; -+ -+ if (! devname) -+ return -1; -+ -+ if (verbose) -+ grub_printf ("Attempt to open drive 0x%x (%s)\n", -+ drive, devname); -+ -+ /* Open read/write, or read-only if that failed. */ -+ if (! read_only) -+ disks[drive].flags = open (devname, O_RDWR); -+ -+ if (disks[drive].flags == -1) -+ { -+ if (read_only || errno == EACCES || errno == EROFS || errno == EPERM) -+ { -+ disks[drive].flags = open (devname, O_RDONLY); -+ if (disks[drive].flags == -1) -+ { -+ assign_device_name (drive, 0); -+ return -1; -+ } -+ } -+ else -+ { -+ assign_device_name (drive, 0); -+ return -1; -+ } -+ } -+ -+ /* Attempt to read the first sector. */ -+ if (read (disks[drive].flags, buf, 512) != 512) -+ { -+ close (disks[drive].flags); -+ disks[drive].flags = -1; -+ assign_device_name (drive, 0); -+ return -1; -+ } -+ -+ if (disks[drive].flags != -1) -+ get_drive_geometry (&disks[drive], device_map, drive); -+ } -+ -+ if (disks[drive].flags == -1) -+ return -1; -+ -+#ifdef __linux__ -+ /* In Linux, invalidate the buffer cache, so that left overs -+ from other program in the cache are flushed and seen by us */ -+ ioctl (disks[drive].flags, BLKFLSBUF, 0); -+#endif -+ -+ *geometry = disks[drive]; -+ return 0; -+} -+ -+/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an -+ error occurs, otherwise return LEN. */ -+static int -+nread (int fd, char *buf, size_t len) -+{ -+ int size = len; -+ -+ while (len) -+ { -+ int ret = read (fd, buf, len); -+ -+ if (ret <= 0) -+ { -+ if (errno == EINTR) -+ continue; -+ else -+ return ret; -+ } -+ -+ len -= ret; -+ buf += ret; -+ } -+ -+ return size; -+} -+ -+/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an -+ error occurs, otherwise return LEN. */ -+static int -+nwrite (int fd, char *buf, size_t len) -+{ -+ int size = len; -+ -+ while (len) -+ { -+ int ret = write (fd, buf, len); -+ -+ if (ret <= 0) -+ { -+ if (errno == EINTR) -+ continue; -+ else -+ return ret; -+ } -+ -+ len -= ret; -+ buf += ret; -+ } -+ -+ return size; -+} -+ -+/* Dump BUF in the format of hexadecimal numbers. */ -+static void -+hex_dump (void *buf, size_t size) -+{ -+ /* FIXME: How to determine which length is readable? */ -+#define MAX_COLUMN 70 -+ -+ /* use unsigned char for numerical computations */ -+ unsigned char *ptr = buf; -+ /* count the width of the line */ -+ int column = 0; -+ /* how many bytes written */ -+ int count = 0; -+ -+ while (size > 0) -+ { -+ /* high 4 bits */ -+ int hi = *ptr >> 4; -+ /* low 4 bits */ -+ int low = *ptr & 0xf; -+ -+ /* grub_printf does not handle prefix number, such as %2x, so -+ format the number by hand... */ -+ grub_printf ("%x%x", hi, low); -+ column += 2; -+ count++; -+ ptr++; -+ size--; -+ -+ /* Insert space or newline with the interval 4 bytes. */ -+ if (size != 0 && (count % 4) == 0) -+ { -+ if (column < MAX_COLUMN) -+ { -+ grub_printf (" "); -+ column++; -+ } -+ else -+ { -+ grub_printf ("\n"); -+ column = 0; -+ } -+ } -+ } -+ -+ /* Add a newline at the end for readability. */ -+ grub_printf ("\n"); -+} -+ -+int -+biosdisk (int subfunc, int drive, struct geometry *geometry, -+ int sector, int nsec, int segment) -+{ -+ char *buf; -+ int fd = geometry->flags; -+ -+ /* Get the file pointer from the geometry, and make sure it matches. */ -+ if (fd == -1 || fd != disks[drive].flags) -+ return BIOSDISK_ERROR_GEOMETRY; -+ -+ /* Seek to the specified location. */ -+#if defined(__linux__) && (!defined(__GLIBC__) || \ -+ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) -+ /* Maybe libc doesn't have large file support. */ -+ { -+ loff_t offset, result; -+ static int _llseek (uint filedes, ulong hi, ulong lo, -+ loff_t *res, uint wh); -+ _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo, -+ loff_t *, res, uint, wh); -+ -+ offset = (loff_t) sector * (loff_t) SECTOR_SIZE; -+ if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET)) -+ return -1; -+ } -+#else -+ { -+ off_t offset = (off_t) sector * (off_t) SECTOR_SIZE; -+ -+ if (lseek (fd, offset, SEEK_SET) != offset) -+ return -1; -+ } -+#endif -+ -+ buf = (char *) (segment << 4); -+ -+ switch (subfunc) -+ { -+ case BIOSDISK_READ: -+#ifdef __linux__ -+ if (sector == 0 && nsec > 1) -+ { -+ /* Work around a bug in linux's ez remapping. Linux remaps all -+ sectors that are read together with the MBR in one read. It -+ should only remap the MBR, so we split the read in two -+ parts. -jochen */ -+ if (nread (fd, buf, SECTOR_SIZE) != SECTOR_SIZE) -+ return -1; -+ buf += SECTOR_SIZE; -+ nsec--; -+ } -+#endif -+ if (nread (fd, buf, nsec * SECTOR_SIZE) != nsec * SECTOR_SIZE) -+ return -1; -+ break; -+ -+ case BIOSDISK_WRITE: -+ if (verbose) -+ { -+ grub_printf ("Write %d sectors starting from %d sector" -+ " to drive 0x%x (%s)\n", -+ nsec, sector, drive, device_map[drive]); -+ hex_dump (buf, nsec * SECTOR_SIZE); -+ } -+ if (! read_only) -+ if (nwrite (fd, buf, nsec * SECTOR_SIZE) != nsec * SECTOR_SIZE) -+ return -1; -+ break; -+ -+ default: -+ grub_printf ("unknown subfunc %d\n", subfunc); -+ break; -+ } -+ -+ return 0; -+} -+ -+ -+void -+stop_floppy (void) -+{ -+ /* NOTUSED */ -+} -+ -+/* Fetch a key from a serial device. */ -+int -+serial_hw_fetch (void) -+{ -+ fd_set fds; -+ struct timeval to; -+ char c; -+ -+ /* Wait only for the serial device. */ -+ FD_ZERO (&fds); -+ FD_SET (serial_fd, &fds); -+ -+ to.tv_sec = 0; -+ to.tv_usec = 0; -+ -+ if (select (serial_fd + 1, &fds, 0, 0, &to) > 0) -+ { -+ if (nread (serial_fd, &c, 1) != 1) -+ stop (); -+ -+ return c; -+ } -+ -+ return -1; -+} -+ -+/* Put a character to a serial device. */ -+void -+serial_hw_put (int c) -+{ -+ char ch = (char) c; -+ -+ if (nwrite (serial_fd, &ch, 1) != 1) -+ stop (); -+} -+ -+void -+serial_hw_delay (void) -+{ -+#ifdef SIMULATE_SLOWNESS_OF_SERIAL -+ struct timeval otv, tv; -+ -+ gettimeofday (&otv, 0); -+ -+ while (1) -+ { -+ long delta; -+ -+ gettimeofday (&tv, 0); -+ delta = tv.tv_usec - otv.tv_usec; -+ if (delta < 0) -+ delta += 1000000; -+ -+ if (delta >= 1000000 / (serial_speed >> 3)) -+ break; -+ } -+#endif /* SIMULATE_SLOWNESS_OF_SERIAL */ -+} -+ -+static speed_t -+get_termios_speed (int speed) -+{ -+ switch (speed) -+ { -+ case 2400: return B2400; -+ case 4800: return B4800; -+ case 9600: return B9600; -+ case 19200: return B19200; -+ case 38400: return B38400; -+#ifdef B57600 -+ case 57600: return B57600; -+#endif -+#ifdef B115200 -+ case 115200: return B115200; -+#endif -+ } -+ -+ return B0; -+} -+ -+/* Get the port number of the unit UNIT. In the grub shell, this doesn't -+ make sense. */ -+unsigned short -+serial_hw_get_port (int unit) -+{ -+ return 0; -+} -+ -+/* Initialize a serial device. In the grub shell, PORT is unused. */ -+int -+serial_hw_init (unsigned short port, unsigned int speed, -+ int word_len, int parity, int stop_bit_len) -+{ -+ struct termios termios; -+ speed_t termios_speed; -+ int i; -+ -+ /* Check if the file name is specified. */ -+ if (! serial_device) -+ return 0; -+ -+ /* If a serial device is already opened, close it first. */ -+ if (serial_fd >= 0) -+ close (serial_fd); -+ -+ /* Open the device file. */ -+ serial_fd = open (serial_device, -+ O_RDWR | O_NOCTTY -+#if defined(O_SYNC) -+ /* O_SYNC is used in Linux (and some others?). */ -+ | O_SYNC -+#elif defined(O_FSYNC) -+ /* O_FSYNC is used in FreeBSD. */ -+ | O_FSYNC -+#endif -+ ); -+ if (serial_fd < 0) -+ return 0; -+ -+ /* Get the termios parameters. */ -+ if (tcgetattr (serial_fd, &termios)) -+ goto fail; -+ -+ /* Raw mode. */ -+ cfmakeraw (&termios); -+ -+ /* Set the speed. */ -+ termios_speed = get_termios_speed (speed); -+ if (termios_speed == B0) -+ goto fail; -+ -+ cfsetispeed (&termios, termios_speed); -+ cfsetospeed (&termios, termios_speed); -+ -+ /* Set the word length. */ -+ termios.c_cflag &= ~CSIZE; -+ switch (word_len) -+ { -+ case UART_5BITS_WORD: -+ termios.c_cflag |= CS5; -+ break; -+ case UART_6BITS_WORD: -+ termios.c_cflag |= CS6; -+ break; -+ case UART_7BITS_WORD: -+ termios.c_cflag |= CS7; -+ break; -+ case UART_8BITS_WORD: -+ termios.c_cflag |= CS8; -+ break; -+ default: -+ goto fail; -+ } -+ -+ /* Set the parity. */ -+ switch (parity) -+ { -+ case UART_NO_PARITY: -+ termios.c_cflag &= ~PARENB; -+ break; -+ case UART_ODD_PARITY: -+ termios.c_cflag |= PARENB; -+ termios.c_cflag |= PARODD; -+ break; -+ case UART_EVEN_PARITY: -+ termios.c_cflag |= PARENB; -+ termios.c_cflag &= ~PARODD; -+ break; -+ default: -+ goto fail; -+ } -+ -+ /* Set the length of stop bit. */ -+ switch (stop_bit_len) -+ { -+ case UART_1_STOP_BIT: -+ termios.c_cflag &= ~CSTOPB; -+ break; -+ case UART_2_STOP_BITS: -+ termios.c_cflag |= CSTOPB; -+ break; -+ default: -+ goto fail; -+ } -+ -+ /* Set the parameters. */ -+ if (tcsetattr (serial_fd, TCSANOW, &termios)) -+ goto fail; -+ -+#ifdef SIMULATE_SLOWNESS_OF_SERIAL -+ serial_speed = speed; -+#endif /* SIMUATE_SLOWNESS_OF_SERIAL */ -+ -+ /* Get rid of the flag TERM_NEED_INIT from the serial terminal. */ -+ for (i = 0; term_table[i].name; i++) -+ { -+ if (strcmp (term_table[i].name, "serial") == 0) -+ { -+ term_table[i].flags &= ~(TERM_NEED_INIT); -+ break; -+ } -+ } -+ -+ return 1; -+ -+ fail: -+ close (serial_fd); -+ serial_fd = -1; -+ return 0; -+} -+ -+/* Set the file name of a serial device (or a pty device). This is a -+ function specific to the grub shell. */ -+void -+serial_set_device (const char *device) -+{ -+ if (serial_device) -+ free (serial_device); -+ -+ serial_device = strdup (device); -+} -+ -+/* There is no difference between console and hercules in the grub shell. */ -+void -+hercules_putchar (int c) -+{ -+ console_putchar (c); -+} -+ -+int -+hercules_getxy (void) -+{ -+ return console_getxy (); -+} -+ -+void -+hercules_gotoxy (int x, int y) -+{ -+ console_gotoxy (x, y); -+} -+ -+void -+hercules_cls (void) -+{ -+ console_cls (); -+} -+ -+void -+hercules_setcolorstate (color_state state) -+{ -+ console_setcolorstate (state); -+} -+ -+void -+hercules_setcolor (int normal_color, int highlight_color) -+{ -+ console_setcolor (normal_color, highlight_color); -+} -+ -+int -+hercules_setcursor (int on) -+{ -+ return 1; -+} -diff -Nur grub-0.97/grub/main.c grub-0.97-patched/grub/main.c ---- grub-0.97/grub/main.c 2003-07-09 13:45:36.000000000 +0200 -+++ grub-0.97-patched/grub/main.c 2012-11-11 17:07:12.720729374 +0100 -@@ -32,6 +32,7 @@ - #define WITHOUT_LIBC_STUBS 1 - #include <shared.h> - #include <term.h> -+#include <device.h> - - char *program_name = 0; - int use_config_file = 1; -@@ -140,10 +141,7 @@ - program_name = argv[0]; - default_boot_drive = boot_drive; - default_install_partition = install_partition; -- if (config_file) -- default_config_file = config_file; -- else -- default_config_file = "NONE"; -+ default_config_file = config_file; - - /* Parse command-line options. */ - do -@@ -192,6 +190,12 @@ - perror ("strtoul"); - exit (1); - } -+ if (boot_drive >= NUM_DISKS) -+ { -+ fprintf (stderr, "boot_drive should be from 0 to %d\n", -+ NUM_DISKS - 1); -+ exit (1); -+ } - break; - - case OPT_NO_CONFIG_FILE: -diff -Nur grub-0.97/grub/main.c.orig grub-0.97-patched/grub/main.c.orig ---- grub-0.97/grub/main.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/grub/main.c.orig 2003-07-09 13:45:36.000000000 +0200 -@@ -0,0 +1,265 @@ -+/* main.c - experimental GRUB stage2 that runs under Unix */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * 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, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+/* Simulator entry point. */ -+int grub_stage2 (void); -+ -+#include <stdio.h> -+#include <getopt.h> -+#include <unistd.h> -+#include <string.h> -+#include <stdlib.h> -+#include <limits.h> -+#include <setjmp.h> -+ -+#define WITHOUT_LIBC_STUBS 1 -+#include <shared.h> -+#include <term.h> -+ -+char *program_name = 0; -+int use_config_file = 1; -+int use_preset_menu = 0; -+#ifdef HAVE_LIBCURSES -+int use_curses = 1; -+#else -+int use_curses = 0; -+#endif -+int verbose = 0; -+int read_only = 0; -+int floppy_disks = 1; -+char *device_map_file = 0; -+static int default_boot_drive; -+static int default_install_partition; -+static char *default_config_file; -+ -+#define OPT_HELP -2 -+#define OPT_VERSION -3 -+#define OPT_HOLD -4 -+#define OPT_CONFIG_FILE -5 -+#define OPT_INSTALL_PARTITION -6 -+#define OPT_BOOT_DRIVE -7 -+#define OPT_NO_CONFIG_FILE -8 -+#define OPT_NO_CURSES -9 -+#define OPT_BATCH -10 -+#define OPT_VERBOSE -11 -+#define OPT_READ_ONLY -12 -+#define OPT_PROBE_SECOND_FLOPPY -13 -+#define OPT_NO_FLOPPY -14 -+#define OPT_DEVICE_MAP -15 -+#define OPT_PRESET_MENU -16 -+#define OPT_NO_PAGER -17 -+#define OPTSTRING "" -+ -+static struct option longopts[] = -+{ -+ {"batch", no_argument, 0, OPT_BATCH}, -+ {"boot-drive", required_argument, 0, OPT_BOOT_DRIVE}, -+ {"config-file", required_argument, 0, OPT_CONFIG_FILE}, -+ {"device-map", required_argument, 0, OPT_DEVICE_MAP}, -+ {"help", no_argument, 0, OPT_HELP}, -+ {"hold", optional_argument, 0, OPT_HOLD}, -+ {"install-partition", required_argument, 0, OPT_INSTALL_PARTITION}, -+ {"no-config-file", no_argument, 0, OPT_NO_CONFIG_FILE}, -+ {"no-curses", no_argument, 0, OPT_NO_CURSES}, -+ {"no-floppy", no_argument, 0, OPT_NO_FLOPPY}, -+ {"no-pager", no_argument, 0, OPT_NO_PAGER}, -+ {"preset-menu", no_argument, 0, OPT_PRESET_MENU}, -+ {"probe-second-floppy", no_argument, 0, OPT_PROBE_SECOND_FLOPPY}, -+ {"read-only", no_argument, 0, OPT_READ_ONLY}, -+ {"verbose", no_argument, 0, OPT_VERBOSE}, -+ {"version", no_argument, 0, OPT_VERSION}, -+ {0}, -+}; -+ -+ -+static void -+usage (int status) -+{ -+ if (status) -+ fprintf (stderr, "Try ``grub --help'' for more information.\n"); -+ else -+ printf ("\ -+Usage: grub [OPTION]...\n\ -+\n\ -+Enter the GRand Unified Bootloader command shell.\n\ -+\n\ -+ --batch turn on batch mode for non-interactive use\n\ -+ --boot-drive=DRIVE specify stage2 boot_drive [default=0x%x]\n\ -+ --config-file=FILE specify stage2 config_file [default=%s]\n\ -+ --device-map=FILE use the device map file FILE\n\ -+ --help display this message and exit\n\ -+ --hold wait until a debugger will attach\n\ -+ --install-partition=PAR specify stage2 install_partition [default=0x%x]\n\ -+ --no-config-file do not use the config file\n\ -+ --no-curses do not use curses\n\ -+ --no-floppy do not probe any floppy drive\n\ -+ --no-pager do not use internal pager\n\ -+ --preset-menu use the preset menu\n\ -+ --probe-second-floppy probe the second floppy drive\n\ -+ --read-only do not write anything to devices\n\ -+ --verbose print verbose messages\n\ -+ --version print version information and exit\n\ -+\n\ -+Report bugs to bug-grub@gnu.org.\n\ -+", -+ default_boot_drive, default_config_file, -+ default_install_partition); -+ -+ exit (status); -+} -+ -+ -+int -+main (int argc, char **argv) -+{ -+ int c; -+ int hold = 0; -+ -+ /* First of all, call sync so that all in-core data is scheduled to be -+ actually written to disks. This is very important because GRUB does -+ not use ordinary stdio interface but raw devices. */ -+ sync (); -+ -+ program_name = argv[0]; -+ default_boot_drive = boot_drive; -+ default_install_partition = install_partition; -+ if (config_file) -+ default_config_file = config_file; -+ else -+ default_config_file = "NONE"; -+ -+ /* Parse command-line options. */ -+ do -+ { -+ c = getopt_long (argc, argv, OPTSTRING, longopts, 0); -+ switch (c) -+ { -+ case EOF: -+ /* Fall through the bottom of the loop. */ -+ break; -+ -+ case OPT_HELP: -+ usage (0); -+ break; -+ -+ case OPT_VERSION: -+ printf ("grub (GNU GRUB " VERSION ")\n"); -+ exit (0); -+ break; -+ -+ case OPT_HOLD: -+ if (! optarg) -+ hold = -1; -+ else -+ hold = atoi (optarg); -+ break; -+ -+ case OPT_CONFIG_FILE: -+ strncpy (config_file, optarg, 127); /* FIXME: arbitrary */ -+ config_file[127] = '\0'; -+ break; -+ -+ case OPT_INSTALL_PARTITION: -+ install_partition = strtoul (optarg, 0, 0); -+ if (install_partition == ULONG_MAX) -+ { -+ perror ("strtoul"); -+ exit (1); -+ } -+ break; -+ -+ case OPT_BOOT_DRIVE: -+ boot_drive = strtoul (optarg, 0, 0); -+ if (boot_drive == ULONG_MAX) -+ { -+ perror ("strtoul"); -+ exit (1); -+ } -+ break; -+ -+ case OPT_NO_CONFIG_FILE: -+ use_config_file = 0; -+ break; -+ -+ case OPT_NO_CURSES: -+ use_curses = 0; -+ break; -+ -+ case OPT_NO_PAGER: -+ use_pager = 0; -+ break; -+ -+ case OPT_BATCH: -+ /* This is the same as "--no-config-file --no-curses --no-pager". */ -+ use_config_file = 0; -+ use_curses = 0; -+ use_pager = 0; -+ break; -+ -+ case OPT_READ_ONLY: -+ read_only = 1; -+ break; -+ -+ case OPT_VERBOSE: -+ verbose = 1; -+ break; -+ -+ case OPT_NO_FLOPPY: -+ floppy_disks = 0; -+ break; -+ -+ case OPT_PROBE_SECOND_FLOPPY: -+ floppy_disks = 2; -+ break; -+ -+ case OPT_DEVICE_MAP: -+ device_map_file = strdup (optarg); -+ break; -+ -+ case OPT_PRESET_MENU: -+ use_preset_menu = 1; -+ break; -+ -+ default: -+ usage (1); -+ } -+ } -+ while (c != EOF); -+ -+ /* Wait until the HOLD variable is cleared by an attached debugger. */ -+ if (hold && verbose) -+ printf ("Run "gdb %s %d", and set HOLD to zero.\n", -+ program_name, (int) getpid ()); -+ while (hold) -+ { -+ if (hold > 0) -+ hold--; -+ -+ sleep (1); -+ } -+ -+ /* If we don't have curses (!HAVE_LIBCURSES or --no-curses or -+ --batch) put terminal to dumb for better handling of line i/o */ -+ if (! use_curses) -+ current_term->flags = TERM_NO_EDIT | TERM_DUMB; -+ -+ /* Transfer control to the stage2 simulator. */ -+ exit (grub_stage2 ()); -+} -diff -Nur grub-0.97/lib/device.c grub-0.97-patched/lib/device.c ---- grub-0.97/lib/device.c 2005-03-28 01:14:25.000000000 +0200 -+++ grub-0.97-patched/lib/device.c 2012-11-11 17:07:12.748730268 +0100 -@@ -69,9 +69,9 @@ - # ifndef CDROM_GET_CAPABILITY - # define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */ - # endif /* ! CDROM_GET_CAPABILITY */ --# ifndef BLKGETSIZE --# define BLKGETSIZE _IO(0x12,96) /* return device size */ --# endif /* ! BLKGETSIZE */ -+# ifndef BLKGETSIZE64 -+# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size */ -+# endif /* ! BLKGETSIZE64 */ - #endif /* __linux__ */ - - /* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with -@@ -131,6 +131,152 @@ - #include <shared.h> - #include <device.h> - -+#if defined(__linux__) -+/* The 2.6 kernel has removed all of the geometry handling for IDE drives -+ * that did fixups for LBA, etc. This means that the geometry we get -+ * with the ioctl has a good chance of being wrong. So, we get to -+ * also know about partition tables and try to read what the geometry -+ * is there. *grumble* Very closely based on code from cfdisk -+ */ -+static void get_kernel_geometry(int fd, long long *cyl, int *heads, int *sectors) { -+ struct hd_geometry hdg; -+ -+ if (ioctl (fd, HDIO_GETGEO, &hdg)) -+ return; -+ -+ *cyl = hdg.cylinders; -+ *heads = hdg.heads; -+ *sectors = hdg.sectors; -+} -+ -+struct partition { -+ unsigned char boot_ind; /* 0x80 - active */ -+ unsigned char head; /* starting head */ -+ unsigned char sector; /* starting sector */ -+ unsigned char cyl; /* starting cylinder */ -+ unsigned char sys_ind; /* What partition type */ -+ unsigned char end_head; /* end head */ -+ unsigned char end_sector; /* end sector */ -+ unsigned char end_cyl; /* end cylinder */ -+ unsigned char start4[4]; /* starting sector counting from 0 */ -+ unsigned char size4[4]; /* nr of sectors in partition */ -+}; -+ -+#define ALIGNMENT 2 -+typedef union { -+ struct { -+ unsigned char align[ALIGNMENT]; -+ unsigned char b[SECTOR_SIZE]; -+ } c; -+ struct { -+ unsigned char align[ALIGNMENT]; -+ unsigned char buffer[0x1BE]; -+ struct partition part[4]; -+ unsigned char magicflag[2]; -+ } p; -+} partition_table; -+ -+#define PART_TABLE_FLAG0 0x55 -+#define PART_TABLE_FLAG1 0xAA -+ -+static void -+get_partition_table_geometry(partition_table *bufp, long long *cyl, int *heads, -+ int *sectors) { -+ struct partition *p; -+ int i,h,s,hh,ss; -+ int first = 1; -+ int bad = 0; -+ -+ if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 || -+ bufp->p.magicflag[1] != PART_TABLE_FLAG1) { -+ /* Matthew Wilcox: slightly friendlier version of -+ fatal(_("Bad signature on partition table"), 3); -+ */ -+ fprintf(stderr, "Unknown partition table signature\n"); -+ return; -+ } -+ -+ hh = ss = 0; -+ for (i=0; i<4; i++) { -+ p = &(bufp->p.part[i]); -+ if (p->sys_ind != 0) { -+ h = p->end_head + 1; -+ s = (p->end_sector & 077); -+ if (first) { -+ hh = h; -+ ss = s; -+ first = 0; -+ } else if (hh != h || ss != s) -+ bad = 1; -+ } -+ } -+ -+ if (!first && !bad) { -+ *heads = hh; -+ *sectors = ss; -+ } -+} -+ -+static long long my_lseek (unsigned int fd, long long offset, -+ unsigned int origin) -+{ -+#if defined(__linux__) && (!defined(__GLIBC__) || \ -+ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) -+ /* Maybe libc doesn't have large file support. */ -+ loff_t offset, result; -+ static int _llseek (uint filedes, ulong hi, ulong lo, -+ loff_t *res, uint wh); -+ _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo, -+ loff_t *, res, uint, wh); -+ -+ if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET) < 0) -+ return (long long) -1; -+ return result; -+#else -+ return lseek(fd, offset, SEEK_SET); -+#endif -+} -+ -+static void get_linux_geometry (int fd, struct geometry *geom) { -+ long long kern_cyl = 0; int kern_head = 0, kern_sectors = 0; -+ long long pt_cyl = 0; int pt_head = 0, pt_sectors = 0; -+ partition_table bufp; -+ char *buff, *buf_unaligned; -+ -+ buf_unaligned = malloc(sizeof(partition_table) + 4095); -+ buff = (char *) (((unsigned long)buf_unaligned + 4096 - 1) & -+ (~(4096-1))); -+ -+ get_kernel_geometry(fd, &kern_cyl, &kern_head, &kern_sectors); -+ -+ if (my_lseek (fd, 0*SECTOR_SIZE, SEEK_SET) < 0) { -+ fprintf(stderr, "Unable to seek"); -+ } -+ -+ if (read(fd, buff, SECTOR_SIZE) == SECTOR_SIZE) { -+ memcpy(bufp.c.b, buff, SECTOR_SIZE); -+ get_partition_table_geometry(&bufp, &pt_cyl, &pt_head, &pt_sectors); -+ } else { -+ fprintf(stderr, "Unable to read partition table: %s\n", strerror(errno)); -+ } -+ -+ if (pt_head && pt_sectors) { -+ int cyl_size; -+ -+ geom->heads = pt_head; -+ geom->sectors = pt_sectors; -+ cyl_size = pt_head * pt_sectors; -+ geom->cylinders = geom->total_sectors/cyl_size; -+ } else { -+ geom->heads = kern_head; -+ geom->sectors = kern_sectors; -+ geom->cylinders = kern_cyl; -+ } -+ -+ return; -+} -+#endif -+ - /* Get the geometry of a drive DRIVE. */ - void - get_drive_geometry (struct geometry *geom, char **map, int drive) -@@ -151,20 +297,16 @@ - #if defined(__linux__) - /* Linux */ - { -- struct hd_geometry hdg; -- unsigned long nr; -+ unsigned long long nr; - -- if (ioctl (fd, HDIO_GETGEO, &hdg)) -- goto fail; -- -- if (ioctl (fd, BLKGETSIZE, &nr)) -+ if (ioctl (fd, BLKGETSIZE64, &nr)) - goto fail; - - /* Got the geometry, so save it. */ -- geom->cylinders = hdg.cylinders; -- geom->heads = hdg.heads; -- geom->sectors = hdg.sectors; -- geom->total_sectors = nr; -+ get_linux_geometry(fd, geom); -+ if (!geom->heads && !geom->cylinders && !geom->sectors) -+ goto fail; -+ geom->total_sectors = nr / 512; - - goto success; - } -@@ -403,10 +545,28 @@ - } - - static void -+get_cciss_disk_name (char *name, int controller, int drive) -+{ -+ sprintf (name, "/dev/cciss/c%dd%d", controller, drive); -+} -+ -+static void -+get_ida_disk_name (char *name, int controller, int drive) -+{ -+ sprintf (name, "/dev/ida/c%dd%d", controller, drive); -+} -+ -+static void - get_ataraid_disk_name (char *name, int unit) - { - sprintf (name, "/dev/ataraid/d%c", unit + '0'); - } -+ -+static void -+get_i2o_disk_name (char *name, char unit) -+{ -+ sprintf (name, "/dev/i2o/hd%c", unit); -+} - #endif - - /* Check if DEVICE can be read. If an error occurs, return zero, -@@ -801,6 +961,97 @@ - } - } - } -+ -+ /* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */ -+ { -+ int unit; -+ -+ for (unit = 'a'; unit < 'f'; unit++) -+ { -+ char name[24]; -+ -+ get_i2o_disk_name (name, unit); -+ if (check_device (name)) -+ { -+ (*map)[num_hd + 0x80] = strdup (name); -+ assert ((*map)[num_hd + 0x80]); -+ -+ /* If the device map file is opened, write the map. */ -+ if (fp) -+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name); -+ -+ num_hd++; -+ } -+ } -+ } -+ -+ /* This is for CCISS, its like the DAC960 - we have -+ /dev/cciss/<controller>d<logical drive>p<partition> -+ -+ It currently supports up to 3 controllers, 10 logical volumes -+ and 10 partitions -+ -+ Code gratuitously copied from DAC960 above. -+ Horms horms@verge.net.au 23rd July 2004 -+ */ -+ { -+ int controller, drive; -+ -+ for (controller = 0; controller < 2; controller++) -+ { -+ for (drive = 0; drive < 9; drive++) -+ { -+ char name[24]; -+ -+ get_cciss_disk_name (name, controller, drive); -+ if (check_device (name)) -+ { -+ (*map)[num_hd + 0x80] = strdup (name); -+ assert ((*map)[num_hd + 0x80]); -+ -+ /* If the device map file is opened, write the map. */ -+ if (fp) -+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name); -+ -+ num_hd++; -+ } -+ } -+ } -+ } -+ -+ /* This is for Compaq Smart Array, its like the DAC960 - we have -+ /dev/ida/<controller>d<logical drive>p<partition> -+ -+ It currently supports up to 3 controllers, 10 logical volumes -+ and 15 partitions -+ -+ Code gratuitously copied from DAC960 above. -+ Piotr Roszatycki dexter@debian.org -+ */ -+ { -+ int controller, drive; -+ -+ for (controller = 0; controller < 2; controller++) -+ { -+ for (drive = 0; drive < 9; drive++) -+ { -+ char name[24]; -+ -+ get_ida_disk_name (name, controller, drive); -+ if (check_device (name)) -+ { -+ (*map)[num_hd + 0x80] = strdup (name); -+ assert ((*map)[num_hd + 0x80]); -+ -+ /* If the device map file is opened, write the map. */ -+ if (fp) -+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name); -+ -+ num_hd++; -+ } -+ } -+ } -+ } - #endif /* __linux__ */ - - /* OK, close the device map file if opened. */ -@@ -844,6 +1095,7 @@ - { - char dev[PATH_MAX]; /* XXX */ - int fd; -+ off_t offset = (off_t) sector * (off_t) SECTOR_SIZE; - - if ((partition & 0x00FF00) != 0x00FF00) - { -@@ -861,6 +1113,14 @@ - if (strcmp (dev + strlen(dev) - 5, "/disc") == 0) - strcpy (dev + strlen(dev) - 5, "/part"); - } -+ else -+ { -+ if ((strncmp (dev, "/dev/ataraid/", 13) == 0) || -+ (strncmp (dev, "/dev/ida/", 9) == 0) || -+ (strncmp (dev, "/dev/cciss/", 11) == 0) || -+ (strncmp (dev, "/dev/rd/", 8) == 0)) -+ strcpy (dev + strlen(dev), "p"); -+ } - sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1); - - /* Open the partition. */ -@@ -870,35 +1130,13 @@ - errnum = ERR_NO_PART; - return 0; - } -- --#if defined(__linux__) && (!defined(__GLIBC__) || \ -- ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))) -- /* Maybe libc doesn't have large file support. */ -- { -- loff_t offset, result; -- static int _llseek (uint filedes, ulong hi, ulong lo, -- loff_t *res, uint wh); -- _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo, -- loff_t *, res, uint, wh); - -- offset = (loff_t) sector * (loff_t) SECTOR_SIZE; -- if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET)) -- { -- errnum = ERR_DEV_VALUES; -- return 0; -- } -- } --#else -- { -- off_t offset = (off_t) sector * (off_t) SECTOR_SIZE; - -- if (lseek (fd, offset, SEEK_SET) != offset) -- { -- errnum = ERR_DEV_VALUES; -- return 0; -- } -- } --#endif -+ if (my_lseek(fd, offset, SEEK_SET) != offset) -+ { -+ errnum = ERR_DEV_VALUES; -+ return 0; -+ } - - if (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE)) - { -diff -Nur grub-0.97/netboot/cs89x0.c grub-0.97-patched/netboot/cs89x0.c ---- grub-0.97/netboot/cs89x0.c 2003-07-09 13:45:37.000000000 +0200 -+++ grub-0.97-patched/netboot/cs89x0.c 2012-11-11 17:07:12.722729437 +0100 -@@ -1,3 +1,21 @@ -+/** -+ Per an email message from Russ Nelson nelson@crynwr.com on -+ 18 March 2008 this file is now licensed under GPL Version 2. -+ -+ From: Russ Nelson nelson@crynwr.com -+ Date: Tue, 18 Mar 2008 12:42:00 -0400 -+ Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot -+ -- quote from email -+ As copyright holder, if I say it doesn't conflict with the GPL, -+ then it doesn't conflict with the GPL. -+ -+ However, there's no point in causing people's brains to overheat, -+ so yes, I grant permission for the code to be relicensed under the -+ GPLv2. Please make sure that this change in licensing makes its -+ way upstream. -russ -+ -- quote from email -+**/ -+ - /* cs89x0.c: A Crystal Semiconductor CS89[02]0 driver for etherboot. */ - /* - Permission is granted to distribute the enclosed cs89x0.[ch] driver -diff -Nur grub-0.97/netboot/cs89x0.h grub-0.97-patched/netboot/cs89x0.h ---- grub-0.97/netboot/cs89x0.h 2003-07-09 13:45:37.000000000 +0200 -+++ grub-0.97-patched/netboot/cs89x0.h 2012-11-11 17:07:12.723729469 +0100 -@@ -1,3 +1,21 @@ -+/** -+ Per an email message from Russ Nelson nelson@crynwr.com on -+ 18 March 2008 this file is now licensed under GPL Version 2. -+ -+ From: Russ Nelson nelson@crynwr.com -+ Date: Tue, 18 Mar 2008 12:42:00 -0400 -+ Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot -+ -- quote from email -+ As copyright holder, if I say it doesn't conflict with the GPL, -+ then it doesn't conflict with the GPL. -+ -+ However, there's no point in causing people's brains to overheat, -+ so yes, I grant permission for the code to be relicensed under the -+ GPLv2. Please make sure that this change in licensing makes its -+ way upstream. -russ -+ -- quote from email -+**/ -+ - /* Copyright, 1988-1992, Russell Nelson, Crynwr Software - - This program is free software; you can redistribute it and/or modify -diff -Nur grub-0.97/netboot/etherboot.h grub-0.97-patched/netboot/etherboot.h ---- grub-0.97/netboot/etherboot.h 2003-07-09 13:45:37.000000000 +0200 -+++ grub-0.97-patched/netboot/etherboot.h 2012-11-11 17:07:12.723729469 +0100 -@@ -531,9 +531,6 @@ - extern int network_ready; - extern struct rom_info rom; - extern struct arptable_t arptable[MAX_ARP]; --extern struct bootpd_t bootp_data; --#define BOOTP_DATA_ADDR (&bootp_data) --extern unsigned char *end_of_rfc1533; - - /* config.c */ - extern struct nic nic; -diff -Nur grub-0.97/netboot/main.c grub-0.97-patched/netboot/main.c ---- grub-0.97/netboot/main.c 2004-05-21 00:19:33.000000000 +0200 -+++ grub-0.97-patched/netboot/main.c 2012-11-11 17:07:12.724729500 +0100 -@@ -56,7 +56,8 @@ - static unsigned long netmask; - static struct bootpd_t bootp_data; - static unsigned long xid; --static unsigned char *end_of_rfc1533 = NULL; -+ -+#define BOOTP_DATA_ADDR (&bootp_data) - - #ifndef NO_DHCP_SUPPORT - #endif /* NO_DHCP_SUPPORT */ -@@ -83,7 +84,9 @@ - RFC2132_MAX_SIZE,2, /* request as much as we can */ - ETH_MAX_MTU / 256, ETH_MAX_MTU % 256, - RFC2132_PARAM_LIST, 4, RFC1533_NETMASK, RFC1533_GATEWAY, -- RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH -+ RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH, -+ /* Vendor class identifier */ -+ RFC2132_VENDOR_CLASS_ID, 10, 'G', 'R', 'U', 'B', 'C', 'l', 'i', 'e', 'n', 't', - }; - - static const unsigned char dhcprequest[] = -@@ -103,6 +106,8 @@ - /* Etherboot vendortags */ - RFC1533_VENDOR_MAGIC, - RFC1533_VENDOR_CONFIGFILE, -+ /* Vendor class identifier */ -+ RFC2132_VENDOR_CLASS_ID, 10, 'G', 'R', 'U', 'B', 'C', 'l', 'i', 'e', 'n', 't', - }; - - #endif /* ! NO_DHCP_SUPPORT */ -@@ -701,7 +706,7 @@ - "adcw %%ax,%0\n\t" /* add carry of previous iteration */ - "loop 1b\n\t" - "adcw $0,%0" /* add carry of last iteration */ -- : "=b" (*sum), "=S"(start), "=c"(len) -+ : "=r" (*sum), "=S"(start), "=c"(len) - : "0"(*sum), "1"(start), "2"(len) - : "ax", "cc" - ); -@@ -967,7 +972,6 @@ - - if (block == 0) - { -- end_of_rfc1533 = NULL; - vendorext_isvalid = 0; - - if (grub_memcmp (p, rfc1533_cookie, 4)) -@@ -1021,7 +1025,7 @@ - } - else if (c == RFC1533_END) - { -- end_of_rfc1533 = endp = p; -+ endp = p; - continue; - } - else if (c == RFC1533_NETMASK) -diff -Nur grub-0.97/netboot/natsemi.c grub-0.97-patched/netboot/natsemi.c ---- grub-0.97/netboot/natsemi.c 2003-07-09 13:45:38.000000000 +0200 -+++ grub-0.97-patched/netboot/natsemi.c 2012-11-11 17:07:12.724729500 +0100 -@@ -608,7 +608,7 @@ - const char *p) /* Packet */ - { - u32 status, to, nstype; -- u32 tx_status; -+ volatile u32 tx_status; - - /* Stop the transmitter */ - outl(TxOff, ioaddr + ChipCmd); -@@ -647,7 +647,7 @@ - - to = currticks() + TX_TIMEOUT; - -- while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to)) -+ while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to)) - /* wait */ ; - - if (currticks() >= to) { -diff -Nur grub-0.97/netboot/pci.c grub-0.97-patched/netboot/pci.c ---- grub-0.97/netboot/pci.c 2003-07-09 13:45:38.000000000 +0200 -+++ grub-0.97-patched/netboot/pci.c 2012-11-11 17:07:07.227553894 +0100 -@@ -105,13 +105,16 @@ - - save_flags(flags); - __asm__( -+ "pushl %%ebx\n\t" /* save %ebx */ - #ifdef ABSOLUTE_WITHOUT_ASTERISK -- "lcall (%%edi)" -+ "lcall (%%edi)\n\t" - #else -- "lcall *(%%edi)" -+ "lcall *(%%edi)\n\t" - #endif -+ "movl %%ebx, %1\n\t" /* capture what was in %ebx */ -+ "popl %%ebx\n\t" /* restore %ebx */ - : "=a" (return_code), -- "=b" (address), -+ "=r" (address), - "=c" (length), - "=d" (entry) - : "0" (service), -@@ -141,18 +144,21 @@ - - save_flags(flags); - __asm__( -+ "pushl %%ebx\n\t" /* save %ebx */ -+ "movl %3, %%ebx\n\t" /* put the value into ebx */ - #ifdef ABSOLUTE_WITHOUT_ASTERISK - "lcall (%%esi)\n\t" - #else - "lcall *(%%esi)\n\t" - #endif - "jc 1f\n\t" -- "xor %%ah, %%ah\n" -+ "popl %%ebx\n\t" /* restore %ebx */ -+ "xor %%ah, %%ah\n\t" - "1:" - : "=c" (*value), - "=a" (ret) - : "1" (PCIBIOS_READ_CONFIG_BYTE), -- "b" (bx), -+ "r" (bx), - "D" ((long) where), - "S" (&pci_indirect)); - restore_flags(flags); -@@ -168,18 +174,21 @@ - - save_flags(flags); - __asm__( -+ "pushl %%ebx\n\t" /* save %ebx */ -+ "movl %3, %%ebx\n\t" /* put the value into ebx */ - #ifdef ABSOLUTE_WITHOUT_ASTERISK - "lcall (%%esi)\n\t" - #else - "lcall *(%%esi)\n\t" - #endif - "jc 1f\n\t" -- "xor %%ah, %%ah\n" -+ "popl %%ebx\n\t" /* restore %ebx */ -+ "xor %%ah, %%ah\n\t" - "1:" - : "=c" (*value), - "=a" (ret) - : "1" (PCIBIOS_READ_CONFIG_WORD), -- "b" (bx), -+ "r" (bx), - "D" ((long) where), - "S" (&pci_indirect)); - restore_flags(flags); -@@ -195,18 +204,21 @@ - - save_flags(flags); - __asm__( -+ "pushl %%ebx\n\t" /* save %ebx */ -+ "movl %3, %%ebx\n\t" /* put the value into ebx */ - #ifdef ABSOLUTE_WITHOUT_ASTERISK - "lcall (%%esi)\n\t" - #else - "lcall *(%%esi)\n\t" - #endif - "jc 1f\n\t" -- "xor %%ah, %%ah\n" -+ "popl %%ebx\n\t" /* restore %ebx */ -+ "xor %%ah, %%ah\n\t" - "1:" - : "=c" (*value), - "=a" (ret) - : "1" (PCIBIOS_READ_CONFIG_DWORD), -- "b" (bx), -+ "r" (bx), - "D" ((long) where), - "S" (&pci_indirect)); - restore_flags(flags); -@@ -222,18 +234,21 @@ - - save_flags(flags); cli(); - __asm__( -+ "pushl %%ebx\n\t" /* save %ebx */ -+ "movl %3, %%ebx\n\t" /* put the value into ebx */ - #ifdef ABSOLUTE_WITHOUT_ASTERISK - "lcall (%%esi)\n\t" - #else - "lcall *(%%esi)\n\t" - #endif - "jc 1f\n\t" -- "xor %%ah, %%ah\n" -+ "popl %%ebx\n\t" /* restore %ebx */ -+ "xor %%ah, %%ah\n\t" - "1:" - : "=a" (ret) - : "0" (PCIBIOS_WRITE_CONFIG_BYTE), - "c" (value), -- "b" (bx), -+ "r" (bx), - "D" ((long) where), - "S" (&pci_indirect)); - restore_flags(flags); -@@ -249,18 +264,21 @@ - - save_flags(flags); cli(); - __asm__( -+ "pushl %%ebx\n\t" /* save %ebx */ -+ "movl %3, %%ebx\n\t" /* put the value into ebx */ - #ifdef ABSOLUTE_WITHOUT_ASTERISK - "lcall (%%esi)\n\t" - #else - "lcall *(%%esi)\n\t" - #endif - "jc 1f\n\t" -- "xor %%ah, %%ah\n" -+ "popl %%ebx\n\t" /* restore %ebx */ -+ "xor %%ah, %%ah\n\t" - "1:" - : "=a" (ret) - : "0" (PCIBIOS_WRITE_CONFIG_WORD), - "c" (value), -- "b" (bx), -+ "r" (bx), - "D" ((long) where), - "S" (&pci_indirect)); - restore_flags(flags); -@@ -276,18 +294,21 @@ - - save_flags(flags); cli(); - __asm__( -+ "pushl %%ebx\n\t" /* save %ebx */ -+ "movl %3, %%ebx\n\t" /* put the value into ebx */ - #ifdef ABSOLUTE_WITHOUT_ASTERISK - "lcall (%%esi)\n\t" - #else - "lcall *(%%esi)\n\t" - #endif - "jc 1f\n\t" -- "xor %%ah, %%ah\n" -+ "popl %%ebx\n\t" /* restore %ebx */ -+ "xor %%ah, %%ah\n\t" - "1:" - : "=a" (ret) - : "0" (PCIBIOS_WRITE_CONFIG_DWORD), - "c" (value), -- "b" (bx), -+ "r" (bx), - "D" ((long) where), - "S" (&pci_indirect)); - restore_flags(flags); -@@ -308,20 +329,22 @@ - - save_flags(flags); - __asm__( -+ "pushl %%ebx\n\t" /* save %ebx */ - #ifdef ABSOLUTE_WITHOUT_ASTERISK - "lcall (%%edi)\n\t" - #else - "lcall *(%%edi)\n\t" - #endif - "jc 1f\n\t" -- "xor %%ah, %%ah\n" -+ "xor %%ah, %%ah\n\t" - "1:\tshl $8, %%eax\n\t" -- "movw %%bx, %%ax" -+ "movw %%bx, %%ax\n\t" -+ "popl %%ebx\n\t" /* restore %ebx */ - : "=d" (signature), - "=a" (pack) - : "1" (PCIBIOS_PCI_BIOS_PRESENT), - "D" (&pci_indirect) -- : "bx", "cx"); -+ : "cx"); - restore_flags(flags); - - present_status = (pack >> 16) & 0xff; -diff -Nur grub-0.97/netboot/sis900.c grub-0.97-patched/netboot/sis900.c ---- grub-0.97/netboot/sis900.c 2003-07-09 13:45:38.000000000 +0200 -+++ grub-0.97-patched/netboot/sis900.c 2012-11-11 17:07:12.725729531 +0100 -@@ -901,7 +901,7 @@ - const char *p) /* Packet */ - { - u32 status, to, nstype; -- u32 tx_status; -+ volatile u32 tx_status; - - /* Stop the transmitter */ - outl(TxDIS, ioaddr + cr); -@@ -940,7 +940,7 @@ - - to = currticks() + TX_TIMEOUT; - -- while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to)) -+ while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to)) - /* wait */ ; - - if (currticks() >= to) { -diff -Nur grub-0.97/stage1/Makefile.am grub-0.97-patched/stage1/Makefile.am ---- grub-0.97/stage1/Makefile.am 2004-07-16 13:44:56.000000000 +0200 -+++ grub-0.97-patched/stage1/Makefile.am 2012-11-11 17:07:12.747730236 +0100 -@@ -1,11 +1,11 @@ --pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor) --nodist_pkglib_DATA = stage1 -+stagedir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor) -+nodist_stage_DATA = stage1 - --CLEANFILES = $(nodist_pkglib_DATA) -+CLEANFILES = $(nodist_stage_DATA) - - # We can't use builtins or standard includes. - AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc --LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00 -+stage1_exec_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00 - - noinst_PROGRAMS = stage1.exec - stage1_exec_SOURCES = stage1.S stage1.h -diff -Nur grub-0.97/stage2/asm.S grub-0.97-patched/stage2/asm.S ---- grub-0.97/stage2/asm.S 2004-06-19 18:55:22.000000000 +0200 -+++ grub-0.97-patched/stage2/asm.S 2012-11-11 17:07:03.850446017 +0100 -@@ -1651,7 +1651,29 @@ - jnz 3f - ret - --3: /* use keyboard controller */ -+3: /* -+ * try to switch gateA20 using PORT92, the "Fast A20 and Init" -+ * register -+ */ -+ mov $0x92, %dx -+ inb %dx, %al -+ /* skip the port92 code if it's unimplemented (read returns 0xff) */ -+ cmpb $0xff, %al -+ jz 6f -+ -+ /* set or clear bit1, the ALT_A20_GATE bit */ -+ movb 4(%esp), %ah -+ testb %ah, %ah -+ jz 4f -+ orb $2, %al -+ jmp 5f -+4: and $0xfd, %al -+ -+ /* clear the INIT_NOW bit don't accidently reset the machine */ -+5: and $0xfe, %al -+ outb %al, %dx -+ -+6: /* use keyboard controller */ - pushl %eax - - call gloop1 -@@ -1661,9 +1683,12 @@ - - gloopint1: - inb $K_STATUS -+ cmpb $0xff, %al -+ jz gloopint1_done - andb $K_IBUF_FUL, %al - jnz gloopint1 - -+gloopint1_done: - movb $KB_OUTPUT_MASK, %al - cmpb $0, 0x8(%esp) - jz gdoit -@@ -1684,6 +1709,8 @@ - - gloop1: - inb $K_STATUS -+ cmpb $0xff, %al -+ jz gloop2ret - andb $K_IBUF_FUL, %al - jnz gloop1 - -@@ -1991,6 +2018,11 @@ - ENTRY(console_getkey) - push %ebp - -+wait_for_key: -+ call EXT_C(console_checkkey) -+ incl %eax -+ jz wait_for_key -+ - call EXT_C(prot_to_real) - .code16 - -@@ -2216,6 +2248,156 @@ - pop %ebx - pop %ebp - ret -+ -+/* graphics mode functions */ -+#ifdef SUPPORT_GRAPHICS -+VARIABLE(cursorX) -+.word 0 -+VARIABLE(cursorY) -+.word 0 -+VARIABLE(cursorCount) -+.word 0 -+VARIABLE(cursorBuf) -+.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+ -+ -+/* -+ * int set_videomode(mode) -+ * BIOS call "INT 10H Function 0h" to set video mode -+ * Call with %ah = 0x0 -+ * %al = video mode -+ * Returns old videomode. -+ */ -+ENTRY(set_videomode) -+ push %ebp -+ push %ebx -+ push %ecx -+ -+ movb 0x10(%esp), %cl -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ xorw %bx, %bx -+ movb $0xf, %ah -+ int $0x10 /* Get Current Video mode */ -+ movb %al, %ch -+ xorb %ah, %ah -+ movb %cl, %al -+ int $0x10 /* Set Video mode */ -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ xorb %ah, %ah -+ movb %ch, %al -+ -+ pop %ecx -+ pop %ebx -+ pop %ebp -+ ret -+ -+ -+/* -+ * unsigned char * graphics_get_font() -+ * BIOS call "INT 10H Function 11h" to set font -+ * Call with %ah = 0x11 -+ */ -+ENTRY(graphics_get_font) -+ push %ebp -+ push %ebx -+ push %ecx -+ push %edx -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ movw $0x1130, %ax -+ movb $6, %bh /* font 8x16 */ -+ int $0x10 -+ movw %bp, %dx -+ movw %es, %cx -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ xorl %eax, %eax -+ movw %cx, %ax -+ shll $4, %eax -+ movw %dx, %ax -+ -+ pop %edx -+ pop %ecx -+ pop %ebx -+ pop %ebp -+ ret -+ -+ -+ -+/* -+ * graphics_set_palette(index, red, green, blue) -+ * BIOS call "INT 10H Function 10h" to set individual dac register -+ * Call with %ah = 0x10 -+ * %bx = register number -+ * %ch = new value for green (0-63) -+ * %cl = new value for blue (0-63) -+ * %dh = new value for red (0-63) -+ */ -+ -+ENTRY(graphics_set_palette) -+ push %ebp -+ push %eax -+ push %ebx -+ push %ecx -+ push %edx -+ -+ movw $0x3c8, %bx /* address write mode register */ -+ -+ /* wait vertical retrace */ -+ -+ movw $0x3da, %dx -+l1b: inb %dx, %al /* wait vertical active display */ -+ test $8, %al -+ jnz l1b -+ -+l2b: inb %dx, %al /* wait vertical retrace */ -+ test $8, %al -+ jnz l2b -+ -+ mov %bx, %dx -+ movb 0x18(%esp), %al /* index */ -+ outb %al, %dx -+ inc %dx -+ -+ movb 0x1c(%esp), %al /* red */ -+ outb %al, %dx -+ -+ movb 0x20(%esp), %al /* green */ -+ outb %al, %dx -+ -+ movb 0x24(%esp), %al /* blue */ -+ outb %al, %dx -+ -+ movw 0x18(%esp), %bx -+ -+ call EXT_C(prot_to_real) -+ .code16 -+ -+ movb %bl, %bh -+ movw $0x1000, %ax -+ int $0x10 -+ -+ DATA32 call EXT_C(real_to_prot) -+ .code32 -+ -+ pop %edx -+ pop %ecx -+ pop %ebx -+ pop %eax -+ pop %ebp -+ ret -+ -+#endif /* SUPPORT_GRAPHICS */ - - /* - * getrtsecs() -diff -Nur grub-0.97/stage2/bios.c grub-0.97-patched/stage2/bios.c ---- grub-0.97/stage2/bios.c 2004-03-27 17:34:04.000000000 +0100 -+++ grub-0.97-patched/stage2/bios.c 2012-11-11 17:07:12.751730363 +0100 -@@ -47,7 +47,7 @@ - return the error number. Otherwise, return 0. */ - int - biosdisk (int read, int drive, struct geometry *geometry, -- int sector, int nsec, int segment) -+ unsigned int sector, int nsec, int segment) - { - int err; - -@@ -60,7 +60,18 @@ - unsigned short blocks; - unsigned long buffer; - unsigned long long block; -- } __attribute__ ((packed)) dap; -+ -+ /* This structure is passed in the stack. A buggy BIOS could write -+ * garbage data to the tail of the struct and hang the machine. So -+ * we need this protection. - Tinybit -+ */ -+ unsigned char dummy[16]; -+ } __attribute__ ((packed)) *dap; -+ -+ /* Even the above protection is not enough to avoid stupid actions by -+ * buggy BIOSes. So we do it in the 0040:0000 segment. - Tinybit -+ */ -+ dap = (struct disk_address_packet *)0x580; - - /* XXX: Don't check the geometry by default, because some buggy - BIOSes don't return the number of total sectors correctly, -@@ -72,15 +83,15 @@ - - /* FIXME: sizeof (DAP) must be 0x10. Should assert that the compiler - can't add any padding. */ -- dap.length = sizeof (dap); -- dap.block = sector; -- dap.blocks = nsec; -- dap.reserved = 0; -+ dap->length = 0x10; -+ dap->block = sector; -+ dap->blocks = nsec; -+ dap->reserved = 0; - /* This is undocumented part. The address is formated in - SEGMENT:ADDRESS. */ -- dap.buffer = segment << 16; -+ dap->buffer = segment << 16; - -- err = biosdisk_int13_extensions ((read + 0x42) << 8, drive, &dap); -+ err = biosdisk_int13_extensions ((read + 0x42) << 8, drive, dap); - - /* #undef NO_INT13_FALLBACK */ - #ifndef NO_INT13_FALLBACK -diff -Nur grub-0.97/stage2/boot.c grub-0.97-patched/stage2/boot.c ---- grub-0.97/stage2/boot.c 2004-03-30 13:44:08.000000000 +0200 -+++ grub-0.97-patched/stage2/boot.c 2012-11-11 17:07:12.727729596 +0100 -@@ -1,7 +1,7 @@ - /* boot.c - load and bootstrap a kernel */ - /* - * GRUB -- GRand Unified Bootloader -- * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. -+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -96,7 +96,7 @@ - lh = (struct linux_kernel_header *) buffer; - - /* ELF loading supported if multiboot, FreeBSD and NetBSD. */ -- if ((type == KERNEL_TYPE_MULTIBOOT -+ if (((type == KERNEL_TYPE_MULTIBOOT && ! (flags & MULTIBOOT_AOUT_KLUDGE)) - || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD - || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0 - || suggested_type == KERNEL_TYPE_NETBSD) -@@ -241,7 +241,7 @@ - } - - if (lh->version >= 0x0202) -- lh->cmd_line_ptr = linux_data_real_addr + LINUX_CL_OFFSET; -+ lh->cmd_line_ptr = linux_data_real_addr + LINUX_CL_0202_PRM_OFFSET; - else - { - lh->cl_magic = LINUX_CL_MAGIC; -@@ -407,6 +407,15 @@ - while (dest < linux_data_tmp_addr + LINUX_CL_END_OFFSET && *src) - *(dest++) = *(src++); - -+ { -+ char *src = skip_to (0, arg); -+ char *dest = linux_data_tmp_addr + LINUX_CL_0202_PRM_OFFSET; -+ -+ while (dest < linux_data_tmp_addr + LINUX_CL_0202_PRM_END_OFFSET && *src) -+ *(dest++) = *(src++); -+ *dest = 0; -+ } -+ - /* Old Linux kernels have problems determining the amount of - the available memory. To work around this problem, we add - the "mem" option to the kernel command line. This has its -@@ -824,8 +833,11 @@ - moveto = (mbi.mem_upper + 0x400) << 10; - - moveto = (moveto - len) & 0xfffff000; -- max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203 -- ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS); -+ max_addr = LINUX_INITRD_MAX_ADDRESS; -+ if (lh->header == LINUX_MAGIC_SIGNATURE && -+ lh->version >= 0x0203 && -+ lh->initrd_addr_max < max_addr) -+ max_addr = lh->initrd_addr_max; - if (moveto + len >= max_addr) - moveto = (max_addr - len) & 0xfffff000; - -diff -Nur grub-0.97/stage2/boot.c.orig grub-0.97-patched/stage2/boot.c.orig ---- grub-0.97/stage2/boot.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/stage2/boot.c.orig 2004-03-30 13:44:08.000000000 +0200 -@@ -0,0 +1,1020 @@ -+/* boot.c - load and bootstrap a kernel */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * 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, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+ -+#include "shared.h" -+ -+#include "freebsd.h" -+#include "imgact_aout.h" -+#include "i386-elf.h" -+ -+static int cur_addr; -+entry_func entry_addr; -+static struct mod_list mll[99]; -+static int linux_mem_size; -+ -+/* -+ * The next two functions, 'load_image' and 'load_module', are the building -+ * blocks of the multiboot loader component. They handle essentially all -+ * of the gory details of loading in a bootable image and the modules. -+ */ -+ -+kernel_t -+load_image (char *kernel, char *arg, kernel_t suggested_type, -+ unsigned long load_flags) -+{ -+ int len, i, exec_type = 0, align_4k = 1; -+ entry_func real_entry_addr = 0; -+ kernel_t type = KERNEL_TYPE_NONE; -+ unsigned long flags = 0, text_len = 0, data_len = 0, bss_len = 0; -+ char *str = 0, *str2 = 0; -+ struct linux_kernel_header *lh; -+ union -+ { -+ struct multiboot_header *mb; -+ struct exec *aout; -+ Elf32_Ehdr *elf; -+ } -+ pu; -+ /* presuming that MULTIBOOT_SEARCH is large enough to encompass an -+ executable header */ -+ unsigned char buffer[MULTIBOOT_SEARCH]; -+ -+ /* sets the header pointer to point to the beginning of the -+ buffer by default */ -+ pu.aout = (struct exec *) buffer; -+ -+ if (!grub_open (kernel)) -+ return KERNEL_TYPE_NONE; -+ -+ if (!(len = grub_read (buffer, MULTIBOOT_SEARCH)) || len < 32) -+ { -+ grub_close (); -+ -+ if (!errnum) -+ errnum = ERR_EXEC_FORMAT; -+ -+ return KERNEL_TYPE_NONE; -+ } -+ -+ for (i = 0; i < len; i++) -+ { -+ if (MULTIBOOT_FOUND ((int) (buffer + i), len - i)) -+ { -+ flags = ((struct multiboot_header *) (buffer + i))->flags; -+ if (flags & MULTIBOOT_UNSUPPORTED) -+ { -+ grub_close (); -+ errnum = ERR_BOOT_FEATURES; -+ return KERNEL_TYPE_NONE; -+ } -+ type = KERNEL_TYPE_MULTIBOOT; -+ str2 = "Multiboot"; -+ break; -+ } -+ } -+ -+ /* Use BUFFER as a linux kernel header, if the image is Linux zImage -+ or bzImage. */ -+ lh = (struct linux_kernel_header *) buffer; -+ -+ /* ELF loading supported if multiboot, FreeBSD and NetBSD. */ -+ if ((type == KERNEL_TYPE_MULTIBOOT -+ || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD -+ || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0 -+ || suggested_type == KERNEL_TYPE_NETBSD) -+ && len > sizeof (Elf32_Ehdr) -+ && BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer)))) -+ { -+ if (type == KERNEL_TYPE_MULTIBOOT) -+ entry_addr = (entry_func) pu.elf->e_entry; -+ else -+ entry_addr = (entry_func) (pu.elf->e_entry & 0xFFFFFF); -+ -+ if (entry_addr < (entry_func) 0x100000) -+ errnum = ERR_BELOW_1MB; -+ -+ /* don't want to deal with ELF program header at some random -+ place in the file -- this generally won't happen */ -+ if (pu.elf->e_phoff == 0 || pu.elf->e_phnum == 0 -+ || ((pu.elf->e_phoff + (pu.elf->e_phentsize * pu.elf->e_phnum)) -+ >= len)) -+ errnum = ERR_EXEC_FORMAT; -+ str = "elf"; -+ -+ if (type == KERNEL_TYPE_NONE) -+ { -+ /* At the moment, there is no way to identify a NetBSD ELF -+ kernel, so rely on the suggested type by the user. */ -+ if (suggested_type == KERNEL_TYPE_NETBSD) -+ { -+ str2 = "NetBSD"; -+ type = suggested_type; -+ } -+ else -+ { -+ str2 = "FreeBSD"; -+ type = KERNEL_TYPE_FREEBSD; -+ } -+ } -+ } -+ else if (flags & MULTIBOOT_AOUT_KLUDGE) -+ { -+ pu.mb = (struct multiboot_header *) (buffer + i); -+ entry_addr = (entry_func) pu.mb->entry_addr; -+ cur_addr = pu.mb->load_addr; -+ /* first offset into file */ -+ grub_seek (i - (pu.mb->header_addr - cur_addr)); -+ -+ /* If the load end address is zero, load the whole contents. */ -+ if (! pu.mb->load_end_addr) -+ pu.mb->load_end_addr = cur_addr + filemax; -+ -+ text_len = pu.mb->load_end_addr - cur_addr; -+ data_len = 0; -+ -+ /* If the bss end address is zero, assume that there is no bss area. */ -+ if (! pu.mb->bss_end_addr) -+ pu.mb->bss_end_addr = pu.mb->load_end_addr; -+ -+ bss_len = pu.mb->bss_end_addr - pu.mb->load_end_addr; -+ -+ if (pu.mb->header_addr < pu.mb->load_addr -+ || pu.mb->load_end_addr <= pu.mb->load_addr -+ || pu.mb->bss_end_addr < pu.mb->load_end_addr -+ || (pu.mb->header_addr - pu.mb->load_addr) > i) -+ errnum = ERR_EXEC_FORMAT; -+ -+ if (cur_addr < 0x100000) -+ errnum = ERR_BELOW_1MB; -+ -+ pu.aout = (struct exec *) buffer; -+ exec_type = 2; -+ str = "kludge"; -+ } -+ else if (len > sizeof (struct exec) && !N_BADMAG ((*(pu.aout)))) -+ { -+ entry_addr = (entry_func) pu.aout->a_entry; -+ -+ if (type == KERNEL_TYPE_NONE) -+ { -+ /* -+ * If it doesn't have a Multiboot header, then presume -+ * it is either a FreeBSD or NetBSD executable. If so, -+ * then use a magic number of normal ordering, ZMAGIC to -+ * determine if it is FreeBSD. -+ * -+ * This is all because freebsd and netbsd seem to require -+ * masking out some address bits... differently for each -+ * one... plus of course we need to know which booting -+ * method to use. -+ */ -+ entry_addr = (entry_func) ((int) entry_addr & 0xFFFFFF); -+ -+ if (buffer[0] == 0xb && buffer[1] == 1) -+ { -+ type = KERNEL_TYPE_FREEBSD; -+ cur_addr = (int) entry_addr; -+ str2 = "FreeBSD"; -+ } -+ else -+ { -+ type = KERNEL_TYPE_NETBSD; -+ cur_addr = (int) entry_addr & 0xF00000; -+ if (N_GETMAGIC ((*(pu.aout))) != NMAGIC) -+ align_4k = 0; -+ str2 = "NetBSD"; -+ } -+ } -+ -+ /* first offset into file */ -+ grub_seek (N_TXTOFF (*(pu.aout))); -+ text_len = pu.aout->a_text; -+ data_len = pu.aout->a_data; -+ bss_len = pu.aout->a_bss; -+ -+ if (cur_addr < 0x100000) -+ errnum = ERR_BELOW_1MB; -+ -+ exec_type = 1; -+ str = "a.out"; -+ } -+ else if (lh->boot_flag == BOOTSEC_SIGNATURE -+ && lh->setup_sects <= LINUX_MAX_SETUP_SECTS) -+ { -+ int big_linux = 0; -+ int setup_sects = lh->setup_sects; -+ -+ if (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0200) -+ { -+ big_linux = (lh->loadflags & LINUX_FLAG_BIG_KERNEL); -+ lh->type_of_loader = LINUX_BOOT_LOADER_TYPE; -+ -+ /* Put the real mode part at as a high location as possible. */ -+ linux_data_real_addr -+ = (char *) ((mbi.mem_lower << 10) - LINUX_SETUP_MOVE_SIZE); -+ /* But it must not exceed the traditional area. */ -+ if (linux_data_real_addr > (char *) LINUX_OLD_REAL_MODE_ADDR) -+ linux_data_real_addr = (char *) LINUX_OLD_REAL_MODE_ADDR; -+ -+ if (lh->version >= 0x0201) -+ { -+ lh->heap_end_ptr = LINUX_HEAP_END_OFFSET; -+ lh->loadflags |= LINUX_FLAG_CAN_USE_HEAP; -+ } -+ -+ if (lh->version >= 0x0202) -+ lh->cmd_line_ptr = linux_data_real_addr + LINUX_CL_OFFSET; -+ else -+ { -+ lh->cl_magic = LINUX_CL_MAGIC; -+ lh->cl_offset = LINUX_CL_OFFSET; -+ lh->setup_move_size = LINUX_SETUP_MOVE_SIZE; -+ } -+ } -+ else -+ { -+ /* Your kernel is quite old... */ -+ lh->cl_magic = LINUX_CL_MAGIC; -+ lh->cl_offset = LINUX_CL_OFFSET; -+ -+ setup_sects = LINUX_DEFAULT_SETUP_SECTS; -+ -+ linux_data_real_addr = (char *) LINUX_OLD_REAL_MODE_ADDR; -+ } -+ -+ /* If SETUP_SECTS is not set, set it to the default (4). */ -+ if (! setup_sects) -+ setup_sects = LINUX_DEFAULT_SETUP_SECTS; -+ -+ data_len = setup_sects << 9; -+ text_len = filemax - data_len - SECTOR_SIZE; -+ -+ linux_data_tmp_addr = (char *) LINUX_BZIMAGE_ADDR + text_len; -+ -+ if (! big_linux -+ && text_len > linux_data_real_addr - (char *) LINUX_ZIMAGE_ADDR) -+ { -+ grub_printf (" linux 'zImage' kernel too big, try 'make bzImage'\n"); -+ errnum = ERR_WONT_FIT; -+ } -+ else if (linux_data_real_addr + LINUX_SETUP_MOVE_SIZE -+ > RAW_ADDR ((char *) (mbi.mem_lower << 10))) -+ errnum = ERR_WONT_FIT; -+ else -+ { -+ grub_printf (" [Linux-%s, setup=0x%x, size=0x%x]\n", -+ (big_linux ? "bzImage" : "zImage"), data_len, text_len); -+ -+ /* Video mode selection support. What a mess! */ -+ /* NOTE: Even the word "mess" is not still enough to -+ represent how wrong and bad the Linux video support is, -+ but I don't want to hear complaints from Linux fanatics -+ any more. -okuji */ -+ { -+ char *vga; -+ -+ /* Find the substring "vga=". */ -+ vga = grub_strstr (arg, "vga="); -+ if (vga) -+ { -+ char *value = vga + 4; -+ int vid_mode; -+ -+ /* Handle special strings. */ -+ if (substring ("normal", value) < 1) -+ vid_mode = LINUX_VID_MODE_NORMAL; -+ else if (substring ("ext", value) < 1) -+ vid_mode = LINUX_VID_MODE_EXTENDED; -+ else if (substring ("ask", value) < 1) -+ vid_mode = LINUX_VID_MODE_ASK; -+ else if (safe_parse_maxint (&value, &vid_mode)) -+ ; -+ else -+ { -+ /* ERRNUM is already set inside the function -+ safe_parse_maxint. */ -+ grub_close (); -+ return KERNEL_TYPE_NONE; -+ } -+ -+ lh->vid_mode = vid_mode; -+ } -+ } -+ -+ /* Check the mem= option to limit memory used for initrd. */ -+ { -+ char *mem; -+ -+ mem = grub_strstr (arg, "mem="); -+ if (mem) -+ { -+ char *value = mem + 4; -+ -+ safe_parse_maxint (&value, &linux_mem_size); -+ switch (errnum) -+ { -+ case ERR_NUMBER_OVERFLOW: -+ /* If an overflow occurs, use the maximum address for -+ initrd instead. This is good, because MAXINT is -+ greater than LINUX_INITRD_MAX_ADDRESS. */ -+ linux_mem_size = LINUX_INITRD_MAX_ADDRESS; -+ errnum = ERR_NONE; -+ break; -+ -+ case ERR_NONE: -+ { -+ int shift = 0; -+ -+ switch (grub_tolower (*value)) -+ { -+ case 'g': -+ shift += 10; -+ case 'm': -+ shift += 10; -+ case 'k': -+ shift += 10; -+ default: -+ break; -+ } -+ -+ /* Check an overflow. */ -+ if (linux_mem_size > (MAXINT >> shift)) -+ linux_mem_size = LINUX_INITRD_MAX_ADDRESS; -+ else -+ linux_mem_size <<= shift; -+ } -+ break; -+ -+ default: -+ linux_mem_size = 0; -+ errnum = ERR_NONE; -+ break; -+ } -+ } -+ else -+ linux_mem_size = 0; -+ } -+ -+ /* It is possible that DATA_LEN + SECTOR_SIZE is greater than -+ MULTIBOOT_SEARCH, so the data may have been read partially. */ -+ if (data_len + SECTOR_SIZE <= MULTIBOOT_SEARCH) -+ grub_memmove (linux_data_tmp_addr, buffer, -+ data_len + SECTOR_SIZE); -+ else -+ { -+ grub_memmove (linux_data_tmp_addr, buffer, MULTIBOOT_SEARCH); -+ grub_read (linux_data_tmp_addr + MULTIBOOT_SEARCH, -+ data_len + SECTOR_SIZE - MULTIBOOT_SEARCH); -+ } -+ -+ if (lh->header != LINUX_MAGIC_SIGNATURE || -+ lh->version < 0x0200) -+ /* Clear the heap space. */ -+ grub_memset (linux_data_tmp_addr + ((setup_sects + 1) << 9), -+ 0, -+ (64 - setup_sects - 1) << 9); -+ -+ /* Copy command-line plus memory hack to staging area. -+ NOTE: Linux has a bug that it doesn't handle multiple spaces -+ between two options and a space after a "mem=" option isn't -+ removed correctly so the arguments to init could be like -+ {"init", "", "", NULL}. This affects some not-very-clever -+ shells. Thus, the code below does a trick to avoid the bug. -+ That is, copy "mem=XXX" to the end of the command-line, and -+ avoid to copy spaces unnecessarily. Hell. */ -+ { -+ char *src = skip_to (0, arg); -+ char *dest = linux_data_tmp_addr + LINUX_CL_OFFSET; -+ -+ while (dest < linux_data_tmp_addr + LINUX_CL_END_OFFSET && *src) -+ *(dest++) = *(src++); -+ -+ /* Old Linux kernels have problems determining the amount of -+ the available memory. To work around this problem, we add -+ the "mem" option to the kernel command line. This has its -+ own drawbacks because newer kernels can determine the -+ memory map more accurately. Boot protocol 2.03, which -+ appeared in Linux 2.4.18, provides a pointer to the kernel -+ version string, so we could check it. But since kernel -+ 2.4.18 and newer are known to detect memory reliably, boot -+ protocol 2.03 already implies that the kernel is new -+ enough. The "mem" option is added if neither of the -+ following conditions is met: -+ 1) The "mem" option is already present. -+ 2) The "kernel" command is used with "--no-mem-option". -+ 3) GNU GRUB is configured not to pass the "mem" option. -+ 4) The kernel supports boot protocol 2.03 or newer. */ -+ if (! grub_strstr (arg, "mem=") -+ && ! (load_flags & KERNEL_LOAD_NO_MEM_OPTION) -+ && lh->version < 0x0203 /* kernel version < 2.4.18 */ -+ && dest + 15 < linux_data_tmp_addr + LINUX_CL_END_OFFSET) -+ { -+ *dest++ = ' '; -+ *dest++ = 'm'; -+ *dest++ = 'e'; -+ *dest++ = 'm'; -+ *dest++ = '='; -+ -+ dest = convert_to_ascii (dest, 'u', (extended_memory + 0x400)); -+ *dest++ = 'K'; -+ } -+ -+ *dest = 0; -+ } -+ -+ /* offset into file */ -+ grub_seek (data_len + SECTOR_SIZE); -+ -+ cur_addr = (int) linux_data_tmp_addr + LINUX_SETUP_MOVE_SIZE; -+ grub_read ((char *) LINUX_BZIMAGE_ADDR, text_len); -+ -+ if (errnum == ERR_NONE) -+ { -+ grub_close (); -+ -+ /* Sanity check. */ -+ if (suggested_type != KERNEL_TYPE_NONE -+ && ((big_linux && suggested_type != KERNEL_TYPE_BIG_LINUX) -+ || (! big_linux && suggested_type != KERNEL_TYPE_LINUX))) -+ { -+ errnum = ERR_EXEC_FORMAT; -+ return KERNEL_TYPE_NONE; -+ } -+ -+ /* Ugly hack. */ -+ linux_text_len = text_len; -+ -+ return big_linux ? KERNEL_TYPE_BIG_LINUX : KERNEL_TYPE_LINUX; -+ } -+ } -+ } -+ else /* no recognizable format */ -+ errnum = ERR_EXEC_FORMAT; -+ -+ /* return if error */ -+ if (errnum) -+ { -+ grub_close (); -+ return KERNEL_TYPE_NONE; -+ } -+ -+ /* fill the multiboot info structure */ -+ mbi.cmdline = (int) arg; -+ mbi.mods_count = 0; -+ mbi.mods_addr = 0; -+ mbi.boot_device = (current_drive << 24) | current_partition; -+ mbi.flags &= ~(MB_INFO_MODS | MB_INFO_AOUT_SYMS | MB_INFO_ELF_SHDR); -+ mbi.syms.a.tabsize = 0; -+ mbi.syms.a.strsize = 0; -+ mbi.syms.a.addr = 0; -+ mbi.syms.a.pad = 0; -+ -+ printf (" [%s-%s", str2, str); -+ -+ str = ""; -+ -+ if (exec_type) /* can be loaded like a.out */ -+ { -+ if (flags & MULTIBOOT_AOUT_KLUDGE) -+ str = "-and-data"; -+ -+ printf (", loadaddr=0x%x, text%s=0x%x", cur_addr, str, text_len); -+ -+ /* read text, then read data */ -+ if (grub_read ((char *) RAW_ADDR (cur_addr), text_len) == text_len) -+ { -+ cur_addr += text_len; -+ -+ if (!(flags & MULTIBOOT_AOUT_KLUDGE)) -+ { -+ /* we have to align to a 4K boundary */ -+ if (align_4k) -+ cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; -+ else -+ printf (", C"); -+ -+ printf (", data=0x%x", data_len); -+ -+ if ((grub_read ((char *) RAW_ADDR (cur_addr), data_len) -+ != data_len) -+ && !errnum) -+ errnum = ERR_EXEC_FORMAT; -+ cur_addr += data_len; -+ } -+ -+ if (!errnum) -+ { -+ memset ((char *) RAW_ADDR (cur_addr), 0, bss_len); -+ cur_addr += bss_len; -+ -+ printf (", bss=0x%x", bss_len); -+ } -+ } -+ else if (!errnum) -+ errnum = ERR_EXEC_FORMAT; -+ -+ if (!errnum && pu.aout->a_syms -+ && pu.aout->a_syms < (filemax - filepos)) -+ { -+ int symtab_err, orig_addr = cur_addr; -+ -+ /* we should align to a 4K boundary here for good measure */ -+ if (align_4k) -+ cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; -+ -+ mbi.syms.a.addr = cur_addr; -+ -+ *((int *) RAW_ADDR (cur_addr)) = pu.aout->a_syms; -+ cur_addr += sizeof (int); -+ -+ printf (", symtab=0x%x", pu.aout->a_syms); -+ -+ if (grub_read ((char *) RAW_ADDR (cur_addr), pu.aout->a_syms) -+ == pu.aout->a_syms) -+ { -+ cur_addr += pu.aout->a_syms; -+ mbi.syms.a.tabsize = pu.aout->a_syms; -+ -+ if (grub_read ((char *) &i, sizeof (int)) == sizeof (int)) -+ { -+ *((int *) RAW_ADDR (cur_addr)) = i; -+ cur_addr += sizeof (int); -+ -+ mbi.syms.a.strsize = i; -+ -+ i -= sizeof (int); -+ -+ printf (", strtab=0x%x", i); -+ -+ symtab_err = (grub_read ((char *) RAW_ADDR (cur_addr), i) -+ != i); -+ cur_addr += i; -+ } -+ else -+ symtab_err = 1; -+ } -+ else -+ symtab_err = 1; -+ -+ if (symtab_err) -+ { -+ printf ("(bad)"); -+ cur_addr = orig_addr; -+ mbi.syms.a.tabsize = 0; -+ mbi.syms.a.strsize = 0; -+ mbi.syms.a.addr = 0; -+ } -+ else -+ mbi.flags |= MB_INFO_AOUT_SYMS; -+ } -+ } -+ else -+ /* ELF executable */ -+ { -+ unsigned loaded = 0, memaddr, memsiz, filesiz; -+ Elf32_Phdr *phdr; -+ -+ /* reset this to zero for now */ -+ cur_addr = 0; -+ -+ /* scan for program segments */ -+ for (i = 0; i < pu.elf->e_phnum; i++) -+ { -+ phdr = (Elf32_Phdr *) -+ (pu.elf->e_phoff + ((int) buffer) -+ + (pu.elf->e_phentsize * i)); -+ if (phdr->p_type == PT_LOAD) -+ { -+ /* offset into file */ -+ grub_seek (phdr->p_offset); -+ filesiz = phdr->p_filesz; -+ -+ if (type == KERNEL_TYPE_FREEBSD || type == KERNEL_TYPE_NETBSD) -+ memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF); -+ else -+ memaddr = RAW_ADDR (phdr->p_paddr); -+ -+ memsiz = phdr->p_memsz; -+ if (memaddr < RAW_ADDR (0x100000)) -+ errnum = ERR_BELOW_1MB; -+ -+ /* If the memory range contains the entry address, get the -+ physical address here. */ -+ if (type == KERNEL_TYPE_MULTIBOOT -+ && (unsigned) entry_addr >= phdr->p_vaddr -+ && (unsigned) entry_addr < phdr->p_vaddr + memsiz) -+ real_entry_addr = (entry_func) ((unsigned) entry_addr -+ + memaddr - phdr->p_vaddr); -+ -+ /* make sure we only load what we're supposed to! */ -+ if (filesiz > memsiz) -+ filesiz = memsiz; -+ /* mark memory as used */ -+ if (cur_addr < memaddr + memsiz) -+ cur_addr = memaddr + memsiz; -+ printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz, -+ memsiz - filesiz); -+ /* increment number of segments */ -+ loaded++; -+ -+ /* load the segment */ -+ if (memcheck (memaddr, memsiz) -+ && grub_read ((char *) memaddr, filesiz) == filesiz) -+ { -+ if (memsiz > filesiz) -+ memset ((char *) (memaddr + filesiz), 0, memsiz - filesiz); -+ } -+ else -+ break; -+ } -+ } -+ -+ if (! errnum) -+ { -+ if (! loaded) -+ errnum = ERR_EXEC_FORMAT; -+ else -+ { -+ /* Load ELF symbols. */ -+ Elf32_Shdr *shdr = NULL; -+ int tab_size, sec_size; -+ int symtab_err = 0; -+ -+ mbi.syms.e.num = pu.elf->e_shnum; -+ mbi.syms.e.size = pu.elf->e_shentsize; -+ mbi.syms.e.shndx = pu.elf->e_shstrndx; -+ -+ /* We should align to a 4K boundary here for good measure. */ -+ if (align_4k) -+ cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; -+ -+ tab_size = pu.elf->e_shentsize * pu.elf->e_shnum; -+ -+ grub_seek (pu.elf->e_shoff); -+ if (grub_read ((char *) RAW_ADDR (cur_addr), tab_size) -+ == tab_size) -+ { -+ mbi.syms.e.addr = cur_addr; -+ shdr = (Elf32_Shdr *) mbi.syms.e.addr; -+ cur_addr += tab_size; -+ -+ printf (", shtab=0x%x", cur_addr); -+ -+ for (i = 0; i < mbi.syms.e.num; i++) -+ { -+ /* This section is a loaded section, -+ so we don't care. */ -+ if (shdr[i].sh_addr != 0) -+ continue; -+ -+ /* This section is empty, so we don't care. */ -+ if (shdr[i].sh_size == 0) -+ continue; -+ -+ /* Align the section to a sh_addralign bits boundary. */ -+ cur_addr = ((cur_addr + shdr[i].sh_addralign) & -+ - (int) shdr[i].sh_addralign); -+ -+ grub_seek (shdr[i].sh_offset); -+ -+ sec_size = shdr[i].sh_size; -+ -+ if (! (memcheck (cur_addr, sec_size) -+ && (grub_read ((char *) RAW_ADDR (cur_addr), -+ sec_size) -+ == sec_size))) -+ { -+ symtab_err = 1; -+ break; -+ } -+ -+ shdr[i].sh_addr = cur_addr; -+ cur_addr += sec_size; -+ } -+ } -+ else -+ symtab_err = 1; -+ -+ if (mbi.syms.e.addr < RAW_ADDR(0x10000)) -+ symtab_err = 1; -+ -+ if (symtab_err) -+ { -+ printf ("(bad)"); -+ mbi.syms.e.num = 0; -+ mbi.syms.e.size = 0; -+ mbi.syms.e.addr = 0; -+ mbi.syms.e.shndx = 0; -+ cur_addr = 0; -+ } -+ else -+ mbi.flags |= MB_INFO_ELF_SHDR; -+ } -+ } -+ } -+ -+ if (! errnum) -+ { -+ grub_printf (", entry=0x%x]\n", (unsigned) entry_addr); -+ -+ /* If the entry address is physically different from that of the ELF -+ header, correct it here. */ -+ if (real_entry_addr) -+ entry_addr = real_entry_addr; -+ } -+ else -+ { -+ putchar ('\n'); -+ type = KERNEL_TYPE_NONE; -+ } -+ -+ grub_close (); -+ -+ /* Sanity check. */ -+ if (suggested_type != KERNEL_TYPE_NONE && suggested_type != type) -+ { -+ errnum = ERR_EXEC_FORMAT; -+ return KERNEL_TYPE_NONE; -+ } -+ -+ return type; -+} -+ -+int -+load_module (char *module, char *arg) -+{ -+ int len; -+ -+ /* if we are supposed to load on 4K boundaries */ -+ cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000; -+ -+ if (!grub_open (module)) -+ return 0; -+ -+ len = grub_read ((char *) cur_addr, -1); -+ if (! len) -+ { -+ grub_close (); -+ return 0; -+ } -+ -+ printf (" [Multiboot-module @ 0x%x, 0x%x bytes]\n", cur_addr, len); -+ -+ /* these two simply need to be set if any modules are loaded at all */ -+ mbi.flags |= MB_INFO_MODS; -+ mbi.mods_addr = (int) mll; -+ -+ mll[mbi.mods_count].cmdline = (int) arg; -+ mll[mbi.mods_count].mod_start = cur_addr; -+ cur_addr += len; -+ mll[mbi.mods_count].mod_end = cur_addr; -+ mll[mbi.mods_count].pad = 0; -+ -+ /* increment number of modules included */ -+ mbi.mods_count++; -+ -+ grub_close (); -+ return 1; -+} -+ -+int -+load_initrd (char *initrd) -+{ -+ int len; -+ unsigned long moveto; -+ unsigned long max_addr; -+ struct linux_kernel_header *lh -+ = (struct linux_kernel_header *) (cur_addr - LINUX_SETUP_MOVE_SIZE); -+ -+#ifndef NO_DECOMPRESSION -+ no_decompression = 1; -+#endif -+ -+ if (! grub_open (initrd)) -+ goto fail; -+ -+ len = grub_read ((char *) cur_addr, -1); -+ if (! len) -+ { -+ grub_close (); -+ goto fail; -+ } -+ -+ if (linux_mem_size) -+ moveto = linux_mem_size; -+ else -+ moveto = (mbi.mem_upper + 0x400) << 10; -+ -+ moveto = (moveto - len) & 0xfffff000; -+ max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203 -+ ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS); -+ if (moveto + len >= max_addr) -+ moveto = (max_addr - len) & 0xfffff000; -+ -+ /* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid -+ the last page. -+ XXX: Linux 2.2.xx has a bug in the memory range check, which is -+ worse than that of Linux 2.3.xx, so avoid the last 64kb. *sigh* */ -+ moveto -= 0x10000; -+ memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len); -+ -+ printf (" [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len); -+ -+ /* FIXME: Should check if the kernel supports INITRD. */ -+ lh->ramdisk_image = RAW_ADDR (moveto); -+ lh->ramdisk_size = len; -+ -+ grub_close (); -+ -+ fail: -+ -+#ifndef NO_DECOMPRESSION -+ no_decompression = 0; -+#endif -+ -+ return ! errnum; -+} -+ -+ -+#ifdef GRUB_UTIL -+/* Dummy function to fake the *BSD boot. */ -+static void -+bsd_boot_entry (int flags, int bootdev, int sym_start, int sym_end, -+ int mem_upper, int mem_lower) -+{ -+ stop (); -+} -+#endif -+ -+ -+/* -+ * All "*_boot" commands depend on the images being loaded into memory -+ * correctly, the variables in this file being set up correctly, and -+ * the root partition being set in the 'saved_drive' and 'saved_partition' -+ * variables. -+ */ -+ -+ -+void -+bsd_boot (kernel_t type, int bootdev, char *arg) -+{ -+ char *str; -+ int clval = 0, i; -+ struct bootinfo bi; -+ -+#ifdef GRUB_UTIL -+ entry_addr = (entry_func) bsd_boot_entry; -+#else -+ stop_floppy (); -+#endif -+ -+ while (*(++arg) && *arg != ' '); -+ str = arg; -+ while (*str) -+ { -+ if (*str == '-') -+ { -+ while (*str && *str != ' ') -+ { -+ if (*str == 'C') -+ clval |= RB_CDROM; -+ if (*str == 'a') -+ clval |= RB_ASKNAME; -+ if (*str == 'b') -+ clval |= RB_HALT; -+ if (*str == 'c') -+ clval |= RB_CONFIG; -+ if (*str == 'd') -+ clval |= RB_KDB; -+ if (*str == 'D') -+ clval |= RB_MULTIPLE; -+ if (*str == 'g') -+ clval |= RB_GDB; -+ if (*str == 'h') -+ clval |= RB_SERIAL; -+ if (*str == 'm') -+ clval |= RB_MUTE; -+ if (*str == 'r') -+ clval |= RB_DFLTROOT; -+ if (*str == 's') -+ clval |= RB_SINGLE; -+ if (*str == 'v') -+ clval |= RB_VERBOSE; -+ str++; -+ } -+ continue; -+ } -+ str++; -+ } -+ -+ if (type == KERNEL_TYPE_FREEBSD) -+ { -+ clval |= RB_BOOTINFO; -+ -+ bi.bi_version = BOOTINFO_VERSION; -+ -+ *arg = 0; -+ while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/'); -+ if (*arg == '/') -+ bi.bi_kernelname = arg + 1; -+ else -+ bi.bi_kernelname = 0; -+ -+ bi.bi_nfs_diskless = 0; -+ bi.bi_n_bios_used = 0; /* this field is apparently unused */ -+ -+ for (i = 0; i < N_BIOS_GEOM; i++) -+ { -+ struct geometry geom; -+ -+ /* XXX Should check the return value. */ -+ get_diskinfo (i + 0x80, &geom); -+ /* FIXME: If HEADS or SECTORS is greater than 255, then this will -+ break the geometry information. That is a drawback of BSD -+ but not of GRUB. */ -+ bi.bi_bios_geom[i] = (((geom.cylinders - 1) << 16) -+ + (((geom.heads - 1) & 0xff) << 8) -+ + (geom.sectors & 0xff)); -+ } -+ -+ bi.bi_size = sizeof (struct bootinfo); -+ bi.bi_memsizes_valid = 1; -+ bi.bi_bios_dev = saved_drive; -+ bi.bi_basemem = mbi.mem_lower; -+ bi.bi_extmem = extended_memory; -+ -+ if (mbi.flags & MB_INFO_AOUT_SYMS) -+ { -+ bi.bi_symtab = mbi.syms.a.addr; -+ bi.bi_esymtab = mbi.syms.a.addr + 4 -+ + mbi.syms.a.tabsize + mbi.syms.a.strsize; -+ } -+#if 0 -+ else if (mbi.flags & MB_INFO_ELF_SHDR) -+ { -+ /* FIXME: Should check if a symbol table exists and, if exists, -+ pass the table to BI. */ -+ } -+#endif -+ else -+ { -+ bi.bi_symtab = 0; -+ bi.bi_esymtab = 0; -+ } -+ -+ /* call entry point */ -+ (*entry_addr) (clval, bootdev, 0, 0, 0, ((int) (&bi))); -+ } -+ else -+ { -+ /* -+ * We now pass the various bootstrap parameters to the loaded -+ * image via the argument list. -+ * -+ * This is the official list: -+ * -+ * arg0 = 8 (magic) -+ * arg1 = boot flags -+ * arg2 = boot device -+ * arg3 = start of symbol table (0 if not loaded) -+ * arg4 = end of symbol table (0 if not loaded) -+ * arg5 = transfer address from image -+ * arg6 = transfer address for next image pointer -+ * arg7 = conventional memory size (640) -+ * arg8 = extended memory size (8196) -+ * -+ * ...in actuality, we just pass the parameters used by the kernel. -+ */ -+ -+ /* call entry point */ -+ unsigned long end_mark; -+ -+ if (mbi.flags & MB_INFO_AOUT_SYMS) -+ end_mark = (mbi.syms.a.addr + 4 -+ + mbi.syms.a.tabsize + mbi.syms.a.strsize); -+ else -+ /* FIXME: it should be mbi.syms.e.size. */ -+ end_mark = 0; -+ -+ (*entry_addr) (clval, bootdev, 0, end_mark, -+ extended_memory, mbi.mem_lower); -+ } -+} -diff -Nur grub-0.97/stage2/builtins.c grub-0.97-patched/stage2/builtins.c ---- grub-0.97/stage2/builtins.c 2005-02-15 22:58:23.000000000 +0100 -+++ grub-0.97-patched/stage2/builtins.c 2012-11-11 17:07:12.729729661 +0100 -@@ -131,63 +131,98 @@ - } - - -+/* blocklist_read_helper nee disk_read_blocklist_func was a nested -+ * function, to which pointers were taken and exposed globally. Even -+ * in the GNU-C nested functions extension, they have local linkage, -+ * and aren't guaranteed to be accessable *at all* outside of their -+ * containing scope. -+ * -+ * Above and beyond all of that, the variables within blocklist_func_context -+ * are originally local variables, with local (not even static) linkage, -+ * from within blocklist_func. These were each referenced by -+ * disk_read_blocklist_func, which is only called from other functions -+ * through a globally scoped pointer. -+ * -+ * The documentation in GCC actually uses the words "all hell will break -+ * loose" to describe this scenario. -+ * -+ * Also, "start_sector" was also used uninitialized, but gcc doesn't warn -+ * about it (possibly because of the scoping madness?) -+ */ -+ -+static struct { -+ int start_sector; -+ int num_sectors; -+ int num_entries; -+ int last_length; -+} blocklist_func_context = { -+ .start_sector = 0, -+ .num_sectors = 0, -+ .num_entries = 0, -+ .last_length = 0 -+}; -+ -+/* Collect contiguous blocks into one entry as many as possible, -+ and print the blocklist notation on the screen. */ -+static void -+blocklist_read_helper (int sector, int offset, int length) -+{ -+ int *start_sector = &blocklist_func_context.start_sector; -+ int *num_sectors = &blocklist_func_context.num_sectors; -+ int *num_entries = &blocklist_func_context.num_entries; -+ int *last_length = &blocklist_func_context.last_length; -+ -+ if (*num_sectors > 0) -+ { -+ if (*start_sector + *num_sectors == sector -+ && offset == 0 && *last_length == SECTOR_SIZE) -+ { -+ *num_sectors++; -+ *last_length = length; -+ return; -+ } -+ else -+ { -+ if (*last_length == SECTOR_SIZE) -+ grub_printf ("%s%d+%d", *num_entries ? "," : "", -+ *start_sector - part_start, *num_sectors); -+ else if (*num_sectors > 1) -+ grub_printf ("%s%d+%d,%d[0-%d]", *num_entries ? "," : "", -+ *start_sector - part_start, *num_sectors-1, -+ *start_sector + *num_sectors-1 - part_start, -+ *last_length); -+ else -+ grub_printf ("%s%d[0-%d]", *num_entries ? "," : "", -+ *start_sector - part_start, *last_length); -+ *num_entries++; -+ *num_sectors = 0; -+ } -+ } -+ -+ if (offset > 0) -+ { -+ grub_printf("%s%d[%d-%d]", *num_entries ? "," : "", -+ sector-part_start, offset, offset+length); -+ *num_entries++; -+ } -+ else -+ { -+ *start_sector = sector; -+ *num_sectors = 1; -+ *last_length = length; -+ } -+} -+ - /* blocklist */ - static int - blocklist_func (char *arg, int flags) - { - char *dummy = (char *) RAW_ADDR (0x100000); -- int start_sector; -- int num_sectors = 0; -- int num_entries = 0; -- int last_length = 0; - -- auto void disk_read_blocklist_func (int sector, int offset, int length); -+ int *start_sector = &blocklist_func_context.start_sector; -+ int *num_sectors = &blocklist_func_context.num_sectors; -+ int *num_entries = &blocklist_func_context.num_entries; - -- /* Collect contiguous blocks into one entry as many as possible, -- and print the blocklist notation on the screen. */ -- auto void disk_read_blocklist_func (int sector, int offset, int length) -- { -- if (num_sectors > 0) -- { -- if (start_sector + num_sectors == sector -- && offset == 0 && last_length == SECTOR_SIZE) -- { -- num_sectors++; -- last_length = length; -- return; -- } -- else -- { -- if (last_length == SECTOR_SIZE) -- grub_printf ("%s%d+%d", num_entries ? "," : "", -- start_sector - part_start, num_sectors); -- else if (num_sectors > 1) -- grub_printf ("%s%d+%d,%d[0-%d]", num_entries ? "," : "", -- start_sector - part_start, num_sectors-1, -- start_sector + num_sectors-1 - part_start, -- last_length); -- else -- grub_printf ("%s%d[0-%d]", num_entries ? "," : "", -- start_sector - part_start, last_length); -- num_entries++; -- num_sectors = 0; -- } -- } -- -- if (offset > 0) -- { -- grub_printf("%s%d[%d-%d]", num_entries ? "," : "", -- sector-part_start, offset, offset+length); -- num_entries++; -- } -- else -- { -- start_sector = sector; -- num_sectors = 1; -- last_length = length; -- } -- } -- - /* Open the file. */ - if (! grub_open (arg)) - return 1; -@@ -206,15 +241,15 @@ - grub_printf (")"); - - /* Read in the whole file to DUMMY. */ -- disk_read_hook = disk_read_blocklist_func; -+ disk_read_hook = blocklist_read_helper; - if (! grub_read (dummy, -1)) - goto fail; - - /* The last entry may not be printed yet. Don't check if it is a - * full sector, since it doesn't matter if we read too much. */ -- if (num_sectors > 0) -- grub_printf ("%s%d+%d", num_entries ? "," : "", -- start_sector - part_start, num_sectors); -+ if (*num_sectors > 0) -+ grub_printf ("%s%d+%d", *num_entries ? "," : "", -+ *start_sector - part_start, *num_sectors); - - grub_printf ("\n"); - -@@ -852,6 +887,138 @@ - }; - #endif /* SUPPORT_NETBOOT */ - -+static int terminal_func (char *arg, int flags); -+ -+#ifdef SUPPORT_GRAPHICS -+ -+static int splashimage_func(char *arg, int flags) { -+ char splashimage[64]; -+ int i; -+ -+ /* filename can only be 64 characters due to our buffer size */ -+ if (strlen(arg) > 63) -+ return 1; -+ if (flags == BUILTIN_CMDLINE) { -+ if (!grub_open(arg)) -+ return 1; -+ grub_close(); -+ } -+ -+ strcpy(splashimage, arg); -+ -+ /* get rid of TERM_NEED_INIT from the graphics terminal. */ -+ for (i = 0; term_table[i].name; i++) { -+ if (grub_strcmp (term_table[i].name, "graphics") == 0) { -+ term_table[i].flags &= ~TERM_NEED_INIT; -+ break; -+ } -+ } -+ -+ graphics_set_splash(splashimage); -+ -+ if (flags == BUILTIN_CMDLINE && graphics_inited) { -+ graphics_end(); -+ graphics_init(); -+ graphics_cls(); -+ } -+ -+ /* FIXME: should we be explicitly switching the terminal as a -+ * side effect here? */ -+ terminal_func("graphics", flags); -+ -+ return 0; -+} -+ -+static struct builtin builtin_splashimage = -+{ -+ "splashimage", -+ splashimage_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "splashimage FILE", -+ "Load FILE as the background image when in graphics mode." -+}; -+ -+ -+/* foreground */ -+static int -+foreground_func(char *arg, int flags) -+{ -+ if (grub_strlen(arg) == 6) { -+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; -+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; -+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; -+ -+ foreground = (r << 16) | (g << 8) | b; -+ if (graphics_inited) -+ graphics_set_palette(15, r, g, b); -+ -+ return (0); -+ } -+ -+ return (1); -+} -+ -+static struct builtin builtin_foreground = -+{ -+ "foreground", -+ foreground_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "foreground RRGGBB", -+ "Sets the foreground color when in graphics mode." -+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." -+}; -+ -+ -+/* background */ -+static int -+background_func(char *arg, int flags) -+{ -+ if (grub_strlen(arg) == 6) { -+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; -+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; -+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; -+ -+ background = (r << 16) | (g << 8) | b; -+ if (graphics_inited) -+ graphics_set_palette(0, r, g, b); -+ return (0); -+ } -+ -+ return (1); -+} -+ -+static struct builtin builtin_background = -+{ -+ "background", -+ background_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "background RRGGBB", -+ "Sets the background color when in graphics mode." -+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." -+}; -+ -+#endif /* SUPPORT_GRAPHICS */ -+ -+ -+/* clear */ -+static int -+clear_func() -+{ -+ if (current_term->cls) -+ current_term->cls(); -+ -+ return 0; -+} -+ -+static struct builtin builtin_clear = -+{ -+ "clear", -+ clear_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "clear", -+ "Clear the screen" -+}; -+ - - /* displayapm */ - static int -@@ -1233,14 +1400,15 @@ - for (drive = 0x80; drive < 0x88; drive++) - { - unsigned long part = 0xFFFFFF; -- unsigned long start, len, offset, ext_offset; -- int type, entry; -+ unsigned long start, len, offset, ext_offset, gpt_offset; -+ int type, entry, gpt_count, gpt_size; - char buf[SECTOR_SIZE]; - - current_drive = drive; - while (next_partition (drive, 0xFFFFFF, &part, &type, - &start, &len, &offset, &entry, -- &ext_offset, buf)) -+ &ext_offset, &gpt_offset, -+ &gpt_count, &gpt_size, buf)) - { - if (type != PC_SLICE_TYPE_NONE - && ! IS_PC_SLICE_TYPE_BSD (type) -@@ -1740,6 +1908,77 @@ - - - /* install */ -+static struct { -+ int saved_sector; -+ int installaddr; -+ int installlist; -+ char *stage2_first_buffer; -+} install_func_context = { -+ .saved_sector = 0, -+ .installaddr = 0, -+ .installlist = 0, -+ .stage2_first_buffer = NULL, -+}; -+ -+/* Save the first sector of Stage2 in STAGE2_SECT. */ -+/* Formerly disk_read_savesect_func with local scope inside install_func */ -+static void -+install_savesect_helper(int sector, int offset, int length) -+{ -+ if (debug) -+ printf ("[%d]", sector); -+ -+ /* ReiserFS has files which sometimes contain data not aligned -+ on sector boundaries. Returning an error is better than -+ silently failing. */ -+ if (offset != 0 || length != SECTOR_SIZE) -+ errnum = ERR_UNALIGNED; -+ -+ install_func_context.saved_sector = sector; -+} -+ -+/* Write SECTOR to INSTALLLIST, and update INSTALLADDR and INSTALLSECT. */ -+/* Formerly disk_read_blocklist_func with local scope inside install_func */ -+static void -+install_blocklist_helper (int sector, int offset, int length) -+{ -+ int *installaddr = &install_func_context.installaddr; -+ int *installlist = &install_func_context.installlist; -+ char **stage2_first_buffer = &install_func_context.stage2_first_buffer; -+ /* Was the last sector full? */ -+ static int last_length = SECTOR_SIZE; -+ -+ if (debug) -+ printf("[%d]", sector); -+ -+ if (offset != 0 || last_length != SECTOR_SIZE) -+ { -+ /* We found a non-sector-aligned data block. */ -+ errnum = ERR_UNALIGNED; -+ return; -+ } -+ -+ last_length = length; -+ -+ if (*((unsigned long *) (*installlist - 4)) -+ + *((unsigned short *) *installlist) != sector -+ || *installlist == (int) *stage2_first_buffer + SECTOR_SIZE + 4) -+ { -+ *installlist -= 8; -+ -+ if (*((unsigned long *) (*installlist - 8))) -+ errnum = ERR_WONT_FIT; -+ else -+ { -+ *((unsigned short *) (*installlist + 2)) = (*installaddr >> 4); -+ *((unsigned long *) (*installlist - 4)) = sector; -+ } -+ } -+ -+ *((unsigned short *) *installlist) += 1; -+ *installaddr += 512; -+} -+ - static int - install_func (char *arg, int flags) - { -@@ -1747,8 +1986,12 @@ - char *stage1_buffer = (char *) RAW_ADDR (0x100000); - char *stage2_buffer = stage1_buffer + SECTOR_SIZE; - char *old_sect = stage2_buffer + SECTOR_SIZE; -- char *stage2_first_buffer = old_sect + SECTOR_SIZE; -- char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE; -+ /* stage2_first_buffer used to be defined as: -+ * char *stage2_first_buffer = old_sect + SECTOR_SIZE; */ -+ char **stage2_first_buffer = &install_func_context.stage2_first_buffer; -+ /* and stage2_second_buffer was: -+ * char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE; */ -+ char *stage2_second_buffer = old_sect + SECTOR_SIZE + SECTOR_SIZE; - /* XXX: Probably SECTOR_SIZE is reasonable. */ - char *config_filename = stage2_second_buffer + SECTOR_SIZE; - char *dummy = config_filename + SECTOR_SIZE; -@@ -1757,10 +2000,11 @@ - int src_drive, src_partition, src_part_start; - int i; - struct geometry dest_geom, src_geom; -- int saved_sector; -+ int *saved_sector = &install_func_context.saved_sector; - int stage2_first_sector, stage2_second_sector; - char *ptr; -- int installaddr, installlist; -+ int *installaddr = &install_func_context.installaddr; -+ int *installlist = &install_func_context.installlist; - /* Point to the location of the name of a configuration file in Stage 2. */ - char *config_file_location; - /* If FILE is a Stage 1.5? */ -@@ -1769,67 +2013,13 @@ - int is_open = 0; - /* If LBA is forced? */ - int is_force_lba = 0; -- /* Was the last sector full? */ -- int last_length = SECTOR_SIZE; -- -+ -+ *stage2_first_buffer = old_sect + SECTOR_SIZE; - #ifdef GRUB_UTIL - /* If the Stage 2 is in a partition mounted by an OS, this will store - the filename under the OS. */ - char *stage2_os_file = 0; - #endif /* GRUB_UTIL */ -- -- auto void disk_read_savesect_func (int sector, int offset, int length); -- auto void disk_read_blocklist_func (int sector, int offset, int length); -- -- /* Save the first sector of Stage2 in STAGE2_SECT. */ -- auto void disk_read_savesect_func (int sector, int offset, int length) -- { -- if (debug) -- printf ("[%d]", sector); -- -- /* ReiserFS has files which sometimes contain data not aligned -- on sector boundaries. Returning an error is better than -- silently failing. */ -- if (offset != 0 || length != SECTOR_SIZE) -- errnum = ERR_UNALIGNED; -- -- saved_sector = sector; -- } -- -- /* Write SECTOR to INSTALLLIST, and update INSTALLADDR and -- INSTALLSECT. */ -- auto void disk_read_blocklist_func (int sector, int offset, int length) -- { -- if (debug) -- printf("[%d]", sector); -- -- if (offset != 0 || last_length != SECTOR_SIZE) -- { -- /* We found a non-sector-aligned data block. */ -- errnum = ERR_UNALIGNED; -- return; -- } -- -- last_length = length; -- -- if (*((unsigned long *) (installlist - 4)) -- + *((unsigned short *) installlist) != sector -- || installlist == (int) stage2_first_buffer + SECTOR_SIZE + 4) -- { -- installlist -= 8; -- -- if (*((unsigned long *) (installlist - 8))) -- errnum = ERR_WONT_FIT; -- else -- { -- *((unsigned short *) (installlist + 2)) = (installaddr >> 4); -- *((unsigned long *) (installlist - 4)) = sector; -- } -- } -- -- *((unsigned short *) installlist) += 1; -- installaddr += 512; -- } - - /* First, check the GNU-style long option. */ - while (1) -@@ -1862,10 +2052,10 @@ - addr = skip_to (0, file); - - /* Get the installation address. */ -- if (! safe_parse_maxint (&addr, &installaddr)) -+ if (! safe_parse_maxint (&addr, installaddr)) - { - /* ADDR is not specified. */ -- installaddr = 0; -+ *installaddr = 0; - ptr = addr; - errnum = 0; - } -@@ -1961,17 +2151,17 @@ - = 0x9090; - - /* Read the first sector of Stage 2. */ -- disk_read_hook = disk_read_savesect_func; -- if (grub_read (stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE) -+ disk_read_hook = install_savesect_helper; -+ if (grub_read (*stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE) - goto fail; - -- stage2_first_sector = saved_sector; -+ stage2_first_sector = *saved_sector; - - /* Read the second sector of Stage 2. */ - if (grub_read (stage2_second_buffer, SECTOR_SIZE) != SECTOR_SIZE) - goto fail; - -- stage2_second_sector = saved_sector; -+ stage2_second_sector = *saved_sector; - - /* Check for the version of Stage 2. */ - if (*((short *) (stage2_second_buffer + STAGE2_VER_MAJ_OFFS)) -@@ -1987,27 +2177,27 @@ - - /* If INSTALLADDR is not specified explicitly in the command-line, - determine it by the Stage 2 id. */ -- if (! installaddr) -+ if (! *installaddr) - { - if (! is_stage1_5) - /* Stage 2. */ -- installaddr = 0x8000; -+ *installaddr = 0x8000; - else - /* Stage 1.5. */ -- installaddr = 0x2000; -+ *installaddr = 0x2000; - } - - *((unsigned long *) (stage1_buffer + STAGE1_STAGE2_SECTOR)) - = stage2_first_sector; - *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_ADDRESS)) -- = installaddr; -+ = *installaddr; - *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_SEGMENT)) -- = installaddr >> 4; -+ = *installaddr >> 4; - -- i = (int) stage2_first_buffer + SECTOR_SIZE - 4; -+ i = (int) *stage2_first_buffer + SECTOR_SIZE - 4; - while (*((unsigned long *) i)) - { -- if (i < (int) stage2_first_buffer -+ if (i < (int) *stage2_first_buffer - || (*((int *) (i - 4)) & 0x80000000) - || *((unsigned short *) i) >= 0xA00 - || *((short *) (i + 2)) == 0) -@@ -2021,13 +2211,13 @@ - i -= 8; - } - -- installlist = (int) stage2_first_buffer + SECTOR_SIZE + 4; -- installaddr += SECTOR_SIZE; -+ *installlist = (int) *stage2_first_buffer + SECTOR_SIZE + 4; -+ *installaddr += SECTOR_SIZE; - - /* Read the whole of Stage2 except for the first sector. */ - grub_seek (SECTOR_SIZE); - -- disk_read_hook = disk_read_blocklist_func; -+ disk_read_hook = install_blocklist_helper; - if (! grub_read (dummy, -1)) - goto fail; - -@@ -2110,7 +2300,7 @@ - /* Skip the first sector. */ - grub_seek (SECTOR_SIZE); - -- disk_read_hook = disk_read_savesect_func; -+ disk_read_hook = install_savesect_helper; - if (grub_read (stage2_buffer, SECTOR_SIZE) != SECTOR_SIZE) - goto fail; - -@@ -2180,7 +2370,7 @@ - else - #endif /* GRUB_UTIL */ - { -- if (! devwrite (saved_sector - part_start, 1, stage2_buffer)) -+ if (! devwrite (*saved_sector - part_start, 1, stage2_buffer)) - goto fail; - } - } -@@ -2202,7 +2392,7 @@ - goto fail; - } - -- if (fwrite (stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) -+ if (fwrite (*stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) - { - fclose (fp); - errnum = ERR_WRITE; -@@ -2229,7 +2419,7 @@ - goto fail; - - if (! devwrite (stage2_first_sector - src_part_start, 1, -- stage2_first_buffer)) -+ *stage2_first_buffer)) - goto fail; - - if (! devwrite (stage2_second_sector - src_part_start, 1, -@@ -2815,8 +3005,8 @@ - { - int new_type; - unsigned long part = 0xFFFFFF; -- unsigned long start, len, offset, ext_offset; -- int entry, type; -+ unsigned long start, len, offset, ext_offset, gpt_offset; -+ int entry, type, gpt_count, gpt_size; - char mbr[512]; - - /* Get the drive and the partition. */ -@@ -2853,8 +3043,15 @@ - /* Look for the partition. */ - while (next_partition (current_drive, 0xFFFFFF, &part, &type, - &start, &len, &offset, &entry, -- &ext_offset, mbr)) -+ &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr)) - { -+ /* The partition may not be a GPT partition. */ -+ if (gpt_offset != 0) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ - if (part == current_partition) - { - /* Found. */ -@@ -3830,15 +4027,15 @@ - { - char tmp[16]; - grub_sprintf (tmp, ",%d", (partition >> 16) & 0xFF); -- grub_strncat (device, tmp, 256); -+ grub_strncat (device, tmp, sizeof (device)); - } - if ((partition & 0x00FF00) != 0x00FF00) - { - char tmp[16]; - grub_sprintf (tmp, ",%c", 'a' + ((partition >> 8) & 0xFF)); -- grub_strncat (device, tmp, 256); -+ grub_strncat (device, tmp, sizeof (device)); - } -- grub_strncat (device, ")", 256); -+ grub_strncat (device, ")", sizeof (device)); - } - - int embed_stage1_5 (char *stage1_5, int drive, int partition) -@@ -4085,7 +4282,7 @@ - }; - - --#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) -+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) - /* terminal */ - static int - terminal_func (char *arg, int flags) -@@ -4244,17 +4441,21 @@ - end: - current_term = term_table + default_term; - current_term->flags = term_flags; -- -+ - if (lines) - max_lines = lines; - else -- /* 24 would be a good default value. */ -- max_lines = 24; -- -+ max_lines = current_term->max_lines; -+ - /* If the interface is currently the command-line, - restart it to repaint the screen. */ -- if (current_term != prev_term && (flags & BUILTIN_CMDLINE)) -+ if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){ -+ if (prev_term->shutdown) -+ prev_term->shutdown(); -+ if (current_term->startup) -+ current_term->startup(); - grub_longjmp (restart_cmdline_env, 0); -+ } - - return 0; - } -@@ -4264,7 +4465,7 @@ - "terminal", - terminal_func, - BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -- "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]", -+ "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]", - "Select a terminal. When multiple terminals are specified, wait until" - " you push any key to continue. If both console and serial are specified," - " the terminal to which you input a key first will be selected. If no" -@@ -4276,7 +4477,7 @@ - " seconds. The option --lines specifies the maximum number of lines." - " The option --silent is used to suppress messages." - }; --#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ -+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ - - - #ifdef SUPPORT_SERIAL -@@ -4795,6 +4996,9 @@ - /* The table of builtin commands. Sorted in dictionary order. */ - struct builtin *builtin_table[] = - { -+#ifdef SUPPORT_GRAPHICS -+ &builtin_background, -+#endif - &builtin_blocklist, - &builtin_boot, - #ifdef SUPPORT_NETBOOT -@@ -4802,6 +5006,7 @@ - #endif /* SUPPORT_NETBOOT */ - &builtin_cat, - &builtin_chainloader, -+ &builtin_clear, - &builtin_cmp, - &builtin_color, - &builtin_configfile, -@@ -4821,6 +5026,9 @@ - &builtin_embed, - &builtin_fallback, - &builtin_find, -+#ifdef SUPPORT_GRAPHICS -+ &builtin_foreground, -+#endif - &builtin_fstest, - &builtin_geometry, - &builtin_halt, -@@ -4864,9 +5072,12 @@ - #endif /* SUPPORT_SERIAL */ - &builtin_setkey, - &builtin_setup, --#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) -+#ifdef SUPPORT_GRAPHICS -+ &builtin_splashimage, -+#endif /* SUPPORT_GRAPHICS */ -+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) - &builtin_terminal, --#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ -+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ - #ifdef SUPPORT_SERIAL - &builtin_terminfo, - #endif /* SUPPORT_SERIAL */ -diff -Nur grub-0.97/stage2/builtins.c.orig grub-0.97-patched/stage2/builtins.c.orig ---- grub-0.97/stage2/builtins.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/stage2/builtins.c.orig 2005-02-15 22:58:23.000000000 +0100 -@@ -0,0 +1,4884 @@ -+/* builtins.c - the GRUB builtin commands */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * 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, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+/* Include stdio.h before shared.h, because we can't define -+ WITHOUT_LIBC_STUBS here. */ -+#ifdef GRUB_UTIL -+# include <stdio.h> -+#endif -+ -+#include <shared.h> -+#include <filesys.h> -+#include <term.h> -+ -+#ifdef SUPPORT_NETBOOT -+# define GRUB 1 -+# include <etherboot.h> -+#endif -+ -+#ifdef SUPPORT_SERIAL -+# include <serial.h> -+# include <terminfo.h> -+#endif -+ -+#ifdef GRUB_UTIL -+# include <device.h> -+#else /* ! GRUB_UTIL */ -+# include <apic.h> -+# include <smp-imps.h> -+#endif /* ! GRUB_UTIL */ -+ -+#ifdef USE_MD5_PASSWORDS -+# include <md5.h> -+#endif -+ -+/* The type of kernel loaded. */ -+kernel_t kernel_type; -+/* The boot device. */ -+static int bootdev; -+/* True when the debug mode is turned on, and false -+ when it is turned off. */ -+int debug = 0; -+/* The default entry. */ -+int default_entry = 0; -+/* The fallback entry. */ -+int fallback_entryno; -+int fallback_entries[MAX_FALLBACK_ENTRIES]; -+/* The number of current entry. */ -+int current_entryno; -+/* The address for Multiboot command-line buffer. */ -+static char *mb_cmdline; -+/* The password. */ -+char *password; -+/* The password type. */ -+password_t password_type; -+/* The flag for indicating that the user is authoritative. */ -+int auth = 0; -+/* The timeout. */ -+int grub_timeout = -1; -+/* Whether to show the menu or not. */ -+int show_menu = 1; -+/* The BIOS drive map. */ -+static unsigned short bios_drive_map[DRIVE_MAP_SIZE + 1]; -+ -+/* Prototypes for allowing straightfoward calling of builtins functions -+ inside other functions. */ -+static int configfile_func (char *arg, int flags); -+ -+/* Initialize the data for builtins. */ -+void -+init_builtins (void) -+{ -+ kernel_type = KERNEL_TYPE_NONE; -+ /* BSD and chainloading evil hacks! */ -+ bootdev = set_bootdev (0); -+ mb_cmdline = (char *) MB_CMDLINE_BUF; -+} -+ -+/* Initialize the data for the configuration file. */ -+void -+init_config (void) -+{ -+ default_entry = 0; -+ password = 0; -+ fallback_entryno = -1; -+ fallback_entries[0] = -1; -+ grub_timeout = -1; -+} -+ -+/* Check a password for correctness. Returns 0 if password was -+ correct, and a value != 0 for error, similarly to strcmp. */ -+int -+check_password (char *entered, char* expected, password_t type) -+{ -+ switch (type) -+ { -+ case PASSWORD_PLAIN: -+ return strcmp (entered, expected); -+ -+#ifdef USE_MD5_PASSWORDS -+ case PASSWORD_MD5: -+ return check_md5_password (entered, expected); -+#endif -+ default: -+ /* unsupported password type: be secure */ -+ return 1; -+ } -+} -+ -+/* Print which sector is read when loading a file. */ -+static void -+disk_read_print_func (int sector, int offset, int length) -+{ -+ grub_printf ("[%d,%d,%d]", sector, offset, length); -+} -+ -+ -+/* blocklist */ -+static int -+blocklist_func (char *arg, int flags) -+{ -+ char *dummy = (char *) RAW_ADDR (0x100000); -+ int start_sector; -+ int num_sectors = 0; -+ int num_entries = 0; -+ int last_length = 0; -+ -+ auto void disk_read_blocklist_func (int sector, int offset, int length); -+ -+ /* Collect contiguous blocks into one entry as many as possible, -+ and print the blocklist notation on the screen. */ -+ auto void disk_read_blocklist_func (int sector, int offset, int length) -+ { -+ if (num_sectors > 0) -+ { -+ if (start_sector + num_sectors == sector -+ && offset == 0 && last_length == SECTOR_SIZE) -+ { -+ num_sectors++; -+ last_length = length; -+ return; -+ } -+ else -+ { -+ if (last_length == SECTOR_SIZE) -+ grub_printf ("%s%d+%d", num_entries ? "," : "", -+ start_sector - part_start, num_sectors); -+ else if (num_sectors > 1) -+ grub_printf ("%s%d+%d,%d[0-%d]", num_entries ? "," : "", -+ start_sector - part_start, num_sectors-1, -+ start_sector + num_sectors-1 - part_start, -+ last_length); -+ else -+ grub_printf ("%s%d[0-%d]", num_entries ? "," : "", -+ start_sector - part_start, last_length); -+ num_entries++; -+ num_sectors = 0; -+ } -+ } -+ -+ if (offset > 0) -+ { -+ grub_printf("%s%d[%d-%d]", num_entries ? "," : "", -+ sector-part_start, offset, offset+length); -+ num_entries++; -+ } -+ else -+ { -+ start_sector = sector; -+ num_sectors = 1; -+ last_length = length; -+ } -+ } -+ -+ /* Open the file. */ -+ if (! grub_open (arg)) -+ return 1; -+ -+ /* Print the device name. */ -+ grub_printf ("(%cd%d", -+ (current_drive & 0x80) ? 'h' : 'f', -+ current_drive & ~0x80); -+ -+ if ((current_partition & 0xFF0000) != 0xFF0000) -+ grub_printf (",%d", (current_partition >> 16) & 0xFF); -+ -+ if ((current_partition & 0x00FF00) != 0x00FF00) -+ grub_printf (",%c", 'a' + ((current_partition >> 8) & 0xFF)); -+ -+ grub_printf (")"); -+ -+ /* Read in the whole file to DUMMY. */ -+ disk_read_hook = disk_read_blocklist_func; -+ if (! grub_read (dummy, -1)) -+ goto fail; -+ -+ /* The last entry may not be printed yet. Don't check if it is a -+ * full sector, since it doesn't matter if we read too much. */ -+ if (num_sectors > 0) -+ grub_printf ("%s%d+%d", num_entries ? "," : "", -+ start_sector - part_start, num_sectors); -+ -+ grub_printf ("\n"); -+ -+ fail: -+ disk_read_hook = 0; -+ grub_close (); -+ return errnum; -+} -+ -+static struct builtin builtin_blocklist = -+{ -+ "blocklist", -+ blocklist_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "blocklist FILE", -+ "Print the blocklist notation of the file FILE." -+}; -+ -+/* boot */ -+static int -+boot_func (char *arg, int flags) -+{ -+ /* Clear the int15 handler if we can boot the kernel successfully. -+ This assumes that the boot code never fails only if KERNEL_TYPE is -+ not KERNEL_TYPE_NONE. Is this assumption is bad? */ -+ if (kernel_type != KERNEL_TYPE_NONE) -+ unset_int15_handler (); -+ -+#ifdef SUPPORT_NETBOOT -+ /* Shut down the networking. */ -+ cleanup_net (); -+#endif -+ -+ switch (kernel_type) -+ { -+ case KERNEL_TYPE_FREEBSD: -+ case KERNEL_TYPE_NETBSD: -+ /* *BSD */ -+ bsd_boot (kernel_type, bootdev, (char *) mbi.cmdline); -+ break; -+ -+ case KERNEL_TYPE_LINUX: -+ /* Linux */ -+ linux_boot (); -+ break; -+ -+ case KERNEL_TYPE_BIG_LINUX: -+ /* Big Linux */ -+ big_linux_boot (); -+ break; -+ -+ case KERNEL_TYPE_CHAINLOADER: -+ /* Chainloader */ -+ -+ /* Check if we should set the int13 handler. */ -+ if (bios_drive_map[0] != 0) -+ { -+ int i; -+ -+ /* Search for SAVED_DRIVE. */ -+ for (i = 0; i < DRIVE_MAP_SIZE; i++) -+ { -+ if (! bios_drive_map[i]) -+ break; -+ else if ((bios_drive_map[i] & 0xFF) == saved_drive) -+ { -+ /* Exchage SAVED_DRIVE with the mapped drive. */ -+ saved_drive = (bios_drive_map[i] >> 8) & 0xFF; -+ break; -+ } -+ } -+ -+ /* Set the handler. This is somewhat dangerous. */ -+ set_int13_handler (bios_drive_map); -+ } -+ -+ gateA20 (0); -+ boot_drive = saved_drive; -+ chain_stage1 (0, BOOTSEC_LOCATION, boot_part_addr); -+ break; -+ -+ case KERNEL_TYPE_MULTIBOOT: -+ /* Multiboot */ -+ multi_boot ((int) entry_addr, (int) &mbi); -+ break; -+ -+ default: -+ errnum = ERR_BOOT_COMMAND; -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_boot = -+{ -+ "boot", -+ boot_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "boot", -+ "Boot the OS/chain-loader which has been loaded." -+}; -+ -+ -+#ifdef SUPPORT_NETBOOT -+/* bootp */ -+static int -+bootp_func (char *arg, int flags) -+{ -+ int with_configfile = 0; -+ -+ if (grub_memcmp (arg, "--with-configfile", sizeof ("--with-configfile") - 1) -+ == 0) -+ { -+ with_configfile = 1; -+ arg = skip_to (0, arg); -+ } -+ -+ if (! bootp ()) -+ { -+ if (errnum == ERR_NONE) -+ errnum = ERR_DEV_VALUES; -+ -+ return 1; -+ } -+ -+ /* Notify the configuration. */ -+ print_network_configuration (); -+ -+ /* XXX: this can cause an endless loop, but there is no easy way to -+ detect such a loop unfortunately. */ -+ if (with_configfile) -+ configfile_func (config_file, flags); -+ -+ return 0; -+} -+ -+static struct builtin builtin_bootp = -+{ -+ "bootp", -+ bootp_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "bootp [--with-configfile]", -+ "Initialize a network device via BOOTP. If the option `--with-configfile'" -+ " is given, try to load a configuration file specified by the 150 vendor" -+ " tag." -+}; -+#endif /* SUPPORT_NETBOOT */ -+ -+ -+/* cat */ -+static int -+cat_func (char *arg, int flags) -+{ -+ char c; -+ -+ if (! grub_open (arg)) -+ return 1; -+ -+ while (grub_read (&c, 1)) -+ { -+ /* Because running "cat" with a binary file can confuse the terminal, -+ print only some characters as they are. */ -+ if (grub_isspace (c) || (c >= ' ' && c <= '~')) -+ grub_putchar (c); -+ else -+ grub_putchar ('?'); -+ } -+ -+ grub_close (); -+ return 0; -+} -+ -+static struct builtin builtin_cat = -+{ -+ "cat", -+ cat_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "cat FILE", -+ "Print the contents of the file FILE." -+}; -+ -+ -+/* chainloader */ -+static int -+chainloader_func (char *arg, int flags) -+{ -+ int force = 0; -+ char *file = arg; -+ -+ /* If the option `--force' is specified? */ -+ if (substring ("--force", arg) <= 0) -+ { -+ force = 1; -+ file = skip_to (0, arg); -+ } -+ -+ /* Open the file. */ -+ if (! grub_open (file)) -+ { -+ kernel_type = KERNEL_TYPE_NONE; -+ return 1; -+ } -+ -+ /* Read the first block. */ -+ if (grub_read ((char *) BOOTSEC_LOCATION, SECTOR_SIZE) != SECTOR_SIZE) -+ { -+ grub_close (); -+ kernel_type = KERNEL_TYPE_NONE; -+ -+ /* This below happens, if a file whose size is less than 512 bytes -+ is loaded. */ -+ if (errnum == ERR_NONE) -+ errnum = ERR_EXEC_FORMAT; -+ -+ return 1; -+ } -+ -+ /* If not loading it forcibly, check for the signature. */ -+ if (! force -+ && (*((unsigned short *) (BOOTSEC_LOCATION + BOOTSEC_SIG_OFFSET)) -+ != BOOTSEC_SIGNATURE)) -+ { -+ grub_close (); -+ errnum = ERR_EXEC_FORMAT; -+ kernel_type = KERNEL_TYPE_NONE; -+ return 1; -+ } -+ -+ grub_close (); -+ kernel_type = KERNEL_TYPE_CHAINLOADER; -+ -+ /* XXX: Windows evil hack. For now, only the first five letters are -+ checked. */ -+ if (IS_PC_SLICE_TYPE_FAT (current_slice) -+ && ! grub_memcmp ((char *) BOOTSEC_LOCATION + BOOTSEC_BPB_SYSTEM_ID, -+ "MSWIN", 5)) -+ *((unsigned long *) (BOOTSEC_LOCATION + BOOTSEC_BPB_HIDDEN_SECTORS)) -+ = part_start; -+ -+ errnum = ERR_NONE; -+ -+ return 0; -+} -+ -+static struct builtin builtin_chainloader = -+{ -+ "chainloader", -+ chainloader_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "chainloader [--force] FILE", -+ "Load the chain-loader FILE. If --force is specified, then load it" -+ " forcibly, whether the boot loader signature is present or not." -+}; -+ -+ -+/* This function could be used to debug new filesystem code. Put a file -+ in the new filesystem and the same file in a well-tested filesystem. -+ Then, run "cmp" with the files. If no output is obtained, probably -+ the code is good, otherwise investigate what's wrong... */ -+/* cmp FILE1 FILE2 */ -+static int -+cmp_func (char *arg, int flags) -+{ -+ /* The filenames. */ -+ char *file1, *file2; -+ /* The addresses. */ -+ char *addr1, *addr2; -+ int i; -+ /* The size of the file. */ -+ int size; -+ -+ /* Get the filenames from ARG. */ -+ file1 = arg; -+ file2 = skip_to (0, arg); -+ if (! *file1 || ! *file2) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ /* Terminate the filenames for convenience. */ -+ nul_terminate (file1); -+ nul_terminate (file2); -+ -+ /* Read the whole data from FILE1. */ -+ addr1 = (char *) RAW_ADDR (0x100000); -+ if (! grub_open (file1)) -+ return 1; -+ -+ /* Get the size. */ -+ size = filemax; -+ if (grub_read (addr1, -1) != size) -+ { -+ grub_close (); -+ return 1; -+ } -+ -+ grub_close (); -+ -+ /* Read the whole data from FILE2. */ -+ addr2 = addr1 + size; -+ if (! grub_open (file2)) -+ return 1; -+ -+ /* Check if the size of FILE2 is equal to the one of FILE2. */ -+ if (size != filemax) -+ { -+ grub_printf ("Differ in size: 0x%x [%s], 0x%x [%s]\n", -+ size, file1, filemax, file2); -+ grub_close (); -+ return 0; -+ } -+ -+ if (! grub_read (addr2, -1)) -+ { -+ grub_close (); -+ return 1; -+ } -+ -+ grub_close (); -+ -+ /* Now compare ADDR1 with ADDR2. */ -+ for (i = 0; i < size; i++) -+ { -+ if (addr1[i] != addr2[i]) -+ grub_printf ("Differ at the offset %d: 0x%x [%s], 0x%x [%s]\n", -+ i, (unsigned) addr1[i], file1, -+ (unsigned) addr2[i], file2); -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_cmp = -+{ -+ "cmp", -+ cmp_func, -+ BUILTIN_CMDLINE, -+ "cmp FILE1 FILE2", -+ "Compare the file FILE1 with the FILE2 and inform the different values" -+ " if any." -+}; -+ -+ -+/* color */ -+/* Set new colors used for the menu interface. Support two methods to -+ specify a color name: a direct integer representation and a symbolic -+ color name. An example of the latter is "blink-light-gray/blue". */ -+static int -+color_func (char *arg, int flags) -+{ -+ char *normal; -+ char *highlight; -+ int new_normal_color; -+ int new_highlight_color; -+ static char *color_list[16] = -+ { -+ "black", -+ "blue", -+ "green", -+ "cyan", -+ "red", -+ "magenta", -+ "brown", -+ "light-gray", -+ "dark-gray", -+ "light-blue", -+ "light-green", -+ "light-cyan", -+ "light-red", -+ "light-magenta", -+ "yellow", -+ "white" -+ }; -+ -+ auto int color_number (char *str); -+ -+ /* Convert the color name STR into the magical number. */ -+ auto int color_number (char *str) -+ { -+ char *ptr; -+ int i; -+ int color = 0; -+ -+ /* Find the separator. */ -+ for (ptr = str; *ptr && *ptr != '/'; ptr++) -+ ; -+ -+ /* If not found, return -1. */ -+ if (! *ptr) -+ return -1; -+ -+ /* Terminate the string STR. */ -+ *ptr++ = 0; -+ -+ /* If STR contains the prefix "blink-", then set the `blink' bit -+ in COLOR. */ -+ if (substring ("blink-", str) <= 0) -+ { -+ color = 0x80; -+ str += 6; -+ } -+ -+ /* Search for the color name. */ -+ for (i = 0; i < 16; i++) -+ if (grub_strcmp (color_list[i], str) == 0) -+ { -+ color |= i; -+ break; -+ } -+ -+ if (i == 16) -+ return -1; -+ -+ str = ptr; -+ nul_terminate (str); -+ -+ /* Search for the color name. */ -+ for (i = 0; i < 8; i++) -+ if (grub_strcmp (color_list[i], str) == 0) -+ { -+ color |= i << 4; -+ break; -+ } -+ -+ if (i == 8) -+ return -1; -+ -+ return color; -+ } -+ -+ normal = arg; -+ highlight = skip_to (0, arg); -+ -+ new_normal_color = color_number (normal); -+ if (new_normal_color < 0 && ! safe_parse_maxint (&normal, &new_normal_color)) -+ return 1; -+ -+ /* The second argument is optional, so set highlight_color -+ to inverted NORMAL_COLOR. */ -+ if (! *highlight) -+ new_highlight_color = ((new_normal_color >> 4) -+ | ((new_normal_color & 0xf) << 4)); -+ else -+ { -+ new_highlight_color = color_number (highlight); -+ if (new_highlight_color < 0 -+ && ! safe_parse_maxint (&highlight, &new_highlight_color)) -+ return 1; -+ } -+ -+ if (current_term->setcolor) -+ current_term->setcolor (new_normal_color, new_highlight_color); -+ -+ return 0; -+} -+ -+static struct builtin builtin_color = -+{ -+ "color", -+ color_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "color NORMAL [HIGHLIGHT]", -+ "Change the menu colors. The color NORMAL is used for most" -+ " lines in the menu, and the color HIGHLIGHT is used to highlight the" -+ " line where the cursor points. If you omit HIGHLIGHT, then the" -+ " inverted color of NORMAL is used for the highlighted line." -+ " The format of a color is "FG/BG". FG and BG are symbolic color names." -+ " A symbolic color name must be one of these: black, blue, green," -+ " cyan, red, magenta, brown, light-gray, dark-gray, light-blue," -+ " light-green, light-cyan, light-red, light-magenta, yellow and white." -+ " But only the first eight names can be used for BG. You can prefix" -+ " "blink-" to FG if you want a blinking foreground color." -+}; -+ -+ -+/* configfile */ -+static int -+configfile_func (char *arg, int flags) -+{ -+ char *new_config = config_file; -+ -+ /* Check if the file ARG is present. */ -+ if (! grub_open (arg)) -+ return 1; -+ -+ grub_close (); -+ -+ /* Copy ARG to CONFIG_FILE. */ -+ while ((*new_config++ = *arg++) != 0) -+ ; -+ -+#ifdef GRUB_UTIL -+ /* Force to load the configuration file. */ -+ use_config_file = 1; -+#endif -+ -+ /* Make sure that the user will not be authoritative. */ -+ auth = 0; -+ -+ /* Restart cmain. */ -+ grub_longjmp (restart_env, 0); -+ -+ /* Never reach here. */ -+ return 0; -+} -+ -+static struct builtin builtin_configfile = -+{ -+ "configfile", -+ configfile_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "configfile FILE", -+ "Load FILE as the configuration file." -+}; -+ -+ -+/* debug */ -+static int -+debug_func (char *arg, int flags) -+{ -+ if (debug) -+ { -+ debug = 0; -+ grub_printf (" Debug mode is turned off\n"); -+ } -+ else -+ { -+ debug = 1; -+ grub_printf (" Debug mode is turned on\n"); -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_debug = -+{ -+ "debug", -+ debug_func, -+ BUILTIN_CMDLINE, -+ "debug", -+ "Turn on/off the debug mode." -+}; -+ -+ -+/* default */ -+static int -+default_func (char *arg, int flags) -+{ -+#ifndef SUPPORT_DISKLESS -+ if (grub_strcmp (arg, "saved") == 0) -+ { -+ default_entry = saved_entryno; -+ return 0; -+ } -+#endif /* SUPPORT_DISKLESS */ -+ -+ if (! safe_parse_maxint (&arg, &default_entry)) -+ return 1; -+ -+ return 0; -+} -+ -+static struct builtin builtin_default = -+{ -+ "default", -+ default_func, -+ BUILTIN_MENU, -+#if 0 -+ "default [NUM | `saved']", -+ "Set the default entry to entry number NUM (if not specified, it is" -+ " 0, the first entry) or the entry number saved by savedefault." -+#endif -+}; -+ -+ -+#ifdef GRUB_UTIL -+/* device */ -+static int -+device_func (char *arg, int flags) -+{ -+ char *drive = arg; -+ char *device; -+ -+ /* Get the drive number from DRIVE. */ -+ if (! set_device (drive)) -+ return 1; -+ -+ /* Get the device argument. */ -+ device = skip_to (0, drive); -+ -+ /* Terminate DEVICE. */ -+ nul_terminate (device); -+ -+ if (! *device || ! check_device (device)) -+ { -+ errnum = ERR_FILE_NOT_FOUND; -+ return 1; -+ } -+ -+ assign_device_name (current_drive, device); -+ -+ return 0; -+} -+ -+static struct builtin builtin_device = -+{ -+ "device", -+ device_func, -+ BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "device DRIVE DEVICE", -+ "Specify DEVICE as the actual drive for a BIOS drive DRIVE. This command" -+ " can be used only in the grub shell." -+}; -+#endif /* GRUB_UTIL */ -+ -+ -+#ifdef SUPPORT_NETBOOT -+/* dhcp */ -+static int -+dhcp_func (char *arg, int flags) -+{ -+ /* For now, this is an alias for bootp. */ -+ return bootp_func (arg, flags); -+} -+ -+static struct builtin builtin_dhcp = -+{ -+ "dhcp", -+ dhcp_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "dhcp", -+ "Initialize a network device via DHCP." -+}; -+#endif /* SUPPORT_NETBOOT */ -+ -+ -+/* displayapm */ -+static int -+displayapm_func (char *arg, int flags) -+{ -+ if (mbi.flags & MB_INFO_APM_TABLE) -+ { -+ grub_printf ("APM BIOS information:\n" -+ " Version: 0x%x\n" -+ " 32-bit CS: 0x%x\n" -+ " Offset: 0x%x\n" -+ " 16-bit CS: 0x%x\n" -+ " 16-bit DS: 0x%x\n" -+ " 32-bit CS length: 0x%x\n" -+ " 16-bit CS length: 0x%x\n" -+ " 16-bit DS length: 0x%x\n", -+ (unsigned) apm_bios_info.version, -+ (unsigned) apm_bios_info.cseg, -+ apm_bios_info.offset, -+ (unsigned) apm_bios_info.cseg_16, -+ (unsigned) apm_bios_info.dseg_16, -+ (unsigned) apm_bios_info.cseg_len, -+ (unsigned) apm_bios_info.cseg_16_len, -+ (unsigned) apm_bios_info.dseg_16_len); -+ } -+ else -+ { -+ grub_printf ("No APM BIOS found or probe failed\n"); -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_displayapm = -+{ -+ "displayapm", -+ displayapm_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "displayapm", -+ "Display APM BIOS information." -+}; -+ -+ -+/* displaymem */ -+static int -+displaymem_func (char *arg, int flags) -+{ -+ if (get_eisamemsize () != -1) -+ grub_printf (" EISA Memory BIOS Interface is present\n"); -+ if (get_mmap_entry ((void *) SCRATCHADDR, 0) != 0 -+ || *((int *) SCRATCHADDR) != 0) -+ grub_printf (" Address Map BIOS Interface is present\n"); -+ -+ grub_printf (" Lower memory: %uK, " -+ "Upper memory (to first chipset hole): %uK\n", -+ mbi.mem_lower, mbi.mem_upper); -+ -+ if (mbi.flags & MB_INFO_MEM_MAP) -+ { -+ struct AddrRangeDesc *map = (struct AddrRangeDesc *) mbi.mmap_addr; -+ int end_addr = mbi.mmap_addr + mbi.mmap_length; -+ -+ grub_printf (" [Address Range Descriptor entries " -+ "immediately follow (values are 64-bit)]\n"); -+ while (end_addr > (int) map) -+ { -+ char *str; -+ -+ if (map->Type == MB_ARD_MEMORY) -+ str = "Usable RAM"; -+ else -+ str = "Reserved"; -+ grub_printf (" %s: Base Address: 0x%x X 4GB + 0x%x,\n" -+ " Length: 0x%x X 4GB + 0x%x bytes\n", -+ str, -+ (unsigned long) (map->BaseAddr >> 32), -+ (unsigned long) (map->BaseAddr & 0xFFFFFFFF), -+ (unsigned long) (map->Length >> 32), -+ (unsigned long) (map->Length & 0xFFFFFFFF)); -+ -+ map = ((struct AddrRangeDesc *) (((int) map) + 4 + map->size)); -+ } -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_displaymem = -+{ -+ "displaymem", -+ displaymem_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "displaymem", -+ "Display what GRUB thinks the system address space map of the" -+ " machine is, including all regions of physical RAM installed." -+}; -+ -+ -+/* dump FROM TO */ -+#ifdef GRUB_UTIL -+static int -+dump_func (char *arg, int flags) -+{ -+ char *from, *to; -+ FILE *fp; -+ char c; -+ -+ from = arg; -+ to = skip_to (0, arg); -+ if (! *from || ! *to) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ nul_terminate (from); -+ nul_terminate (to); -+ -+ if (! grub_open (from)) -+ return 1; -+ -+ fp = fopen (to, "w"); -+ if (! fp) -+ { -+ errnum = ERR_WRITE; -+ return 1; -+ } -+ -+ while (grub_read (&c, 1)) -+ if (fputc (c, fp) == EOF) -+ { -+ errnum = ERR_WRITE; -+ fclose (fp); -+ return 1; -+ } -+ -+ if (fclose (fp) == EOF) -+ { -+ errnum = ERR_WRITE; -+ return 1; -+ } -+ -+ grub_close (); -+ return 0; -+} -+ -+static struct builtin builtin_dump = -+ { -+ "dump", -+ dump_func, -+ BUILTIN_CMDLINE, -+ "dump FROM TO", -+ "Dump the contents of the file FROM to the file TO. FROM must be" -+ " a GRUB file and TO must be an OS file." -+ }; -+#endif /* GRUB_UTIL */ -+ -+ -+static char embed_info[32]; -+/* embed */ -+/* Embed a Stage 1.5 in the first cylinder after MBR or in the -+ bootloader block in a FFS. */ -+static int -+embed_func (char *arg, int flags) -+{ -+ char *stage1_5; -+ char *device; -+ char *stage1_5_buffer = (char *) RAW_ADDR (0x100000); -+ int len, size; -+ int sector; -+ -+ stage1_5 = arg; -+ device = skip_to (0, stage1_5); -+ -+ /* Open a Stage 1.5. */ -+ if (! grub_open (stage1_5)) -+ return 1; -+ -+ /* Read the whole of the Stage 1.5. */ -+ len = grub_read (stage1_5_buffer, -1); -+ grub_close (); -+ -+ if (errnum) -+ return 1; -+ -+ size = (len + SECTOR_SIZE - 1) / SECTOR_SIZE; -+ -+ /* Get the device where the Stage 1.5 will be embedded. */ -+ set_device (device); -+ if (errnum) -+ return 1; -+ -+ if (current_partition == 0xFFFFFF) -+ { -+ /* Embed it after the MBR. */ -+ -+ char mbr[SECTOR_SIZE]; -+ char ezbios_check[2*SECTOR_SIZE]; -+ int i; -+ -+ /* Open the partition. */ -+ if (! open_partition ()) -+ return 1; -+ -+ /* No floppy has MBR. */ -+ if (! (current_drive & 0x80)) -+ { -+ errnum = ERR_DEV_VALUES; -+ return 1; -+ } -+ -+ /* Read the MBR of CURRENT_DRIVE. */ -+ if (! rawread (current_drive, PC_MBR_SECTOR, 0, SECTOR_SIZE, mbr)) -+ return 1; -+ -+ /* Sanity check. */ -+ if (! PC_MBR_CHECK_SIG (mbr)) -+ { -+ errnum = ERR_BAD_PART_TABLE; -+ return 1; -+ } -+ -+ /* Check if the disk can store the Stage 1.5. */ -+ for (i = 0; i < 4; i++) -+ if (PC_SLICE_TYPE (mbr, i) && PC_SLICE_START (mbr, i) - 1 < size) -+ { -+ errnum = ERR_NO_DISK_SPACE; -+ return 1; -+ } -+ -+ /* Check for EZ-BIOS signature. It should be in the third -+ * sector, but due to remapping it can appear in the second, so -+ * load and check both. -+ */ -+ if (! rawread (current_drive, 1, 0, 2 * SECTOR_SIZE, ezbios_check)) -+ return 1; -+ -+ if (! memcmp (ezbios_check + 3, "AERMH", 5) -+ || ! memcmp (ezbios_check + 512 + 3, "AERMH", 5)) -+ { -+ /* The space after the MBR is used by EZ-BIOS which we must -+ * not overwrite. -+ */ -+ errnum = ERR_NO_DISK_SPACE; -+ return 1; -+ } -+ -+ sector = 1; -+ } -+ else -+ { -+ /* Embed it in the bootloader block in the filesystem. */ -+ int start_sector; -+ -+ /* Open the partition. */ -+ if (! open_device ()) -+ return 1; -+ -+ /* Check if the current slice supports embedding. */ -+ if (fsys_table[fsys_type].embed_func == 0 -+ || ! fsys_table[fsys_type].embed_func (&start_sector, size)) -+ { -+ errnum = ERR_DEV_VALUES; -+ return 1; -+ } -+ -+ sector = part_start + start_sector; -+ } -+ -+ /* Clear the cache. */ -+ buf_track = -1; -+ -+ /* Now perform the embedding. */ -+ if (! devwrite (sector - part_start, size, stage1_5_buffer)) -+ return 1; -+ -+ grub_printf (" %d sectors are embedded.\n", size); -+ grub_sprintf (embed_info, "%d+%d", sector - part_start, size); -+ return 0; -+} -+ -+static struct builtin builtin_embed = -+{ -+ "embed", -+ embed_func, -+ BUILTIN_CMDLINE, -+ "embed STAGE1_5 DEVICE", -+ "Embed the Stage 1.5 STAGE1_5 in the sectors after MBR if DEVICE" -+ " is a drive, or in the "bootloader" area if DEVICE is a FFS partition." -+ " Print the number of sectors which STAGE1_5 occupies if successful." -+}; -+ -+ -+/* fallback */ -+static int -+fallback_func (char *arg, int flags) -+{ -+ int i = 0; -+ -+ while (*arg) -+ { -+ int entry; -+ int j; -+ -+ if (! safe_parse_maxint (&arg, &entry)) -+ return 1; -+ -+ /* Remove duplications to prevent infinite looping. */ -+ for (j = 0; j < i; j++) -+ if (entry == fallback_entries[j]) -+ break; -+ if (j != i) -+ continue; -+ -+ fallback_entries[i++] = entry; -+ if (i == MAX_FALLBACK_ENTRIES) -+ break; -+ -+ arg = skip_to (0, arg); -+ } -+ -+ if (i < MAX_FALLBACK_ENTRIES) -+ fallback_entries[i] = -1; -+ -+ fallback_entryno = (i == 0) ? -1 : 0; -+ -+ return 0; -+} -+ -+static struct builtin builtin_fallback = -+{ -+ "fallback", -+ fallback_func, -+ BUILTIN_MENU, -+#if 0 -+ "fallback NUM...", -+ "Go into unattended boot mode: if the default boot entry has any" -+ " errors, instead of waiting for the user to do anything, it" -+ " immediately starts over using the NUM entry (same numbering as the" -+ " `default' command). This obviously won't help if the machine" -+ " was rebooted by a kernel that GRUB loaded." -+#endif -+}; -+ -+ -+/* find */ -+/* Search for the filename ARG in all of partitions. */ -+static int -+find_func (char *arg, int flags) -+{ -+ char *filename = arg; -+ unsigned long drive; -+ unsigned long tmp_drive = saved_drive; -+ unsigned long tmp_partition = saved_partition; -+ int got_file = 0; -+ -+ /* Floppies. */ -+ for (drive = 0; drive < 8; drive++) -+ { -+ current_drive = drive; -+ current_partition = 0xFFFFFF; -+ -+ if (open_device ()) -+ { -+ saved_drive = current_drive; -+ saved_partition = current_partition; -+ if (grub_open (filename)) -+ { -+ grub_close (); -+ grub_printf (" (fd%d)\n", drive); -+ got_file = 1; -+ } -+ } -+ -+ errnum = ERR_NONE; -+ } -+ -+ /* Hard disks. */ -+ for (drive = 0x80; drive < 0x88; drive++) -+ { -+ unsigned long part = 0xFFFFFF; -+ unsigned long start, len, offset, ext_offset; -+ int type, entry; -+ char buf[SECTOR_SIZE]; -+ -+ current_drive = drive; -+ while (next_partition (drive, 0xFFFFFF, &part, &type, -+ &start, &len, &offset, &entry, -+ &ext_offset, buf)) -+ { -+ if (type != PC_SLICE_TYPE_NONE -+ && ! IS_PC_SLICE_TYPE_BSD (type) -+ && ! IS_PC_SLICE_TYPE_EXTENDED (type)) -+ { -+ current_partition = part; -+ if (open_device ()) -+ { -+ saved_drive = current_drive; -+ saved_partition = current_partition; -+ if (grub_open (filename)) -+ { -+ int bsd_part = (part >> 8) & 0xFF; -+ int pc_slice = part >> 16; -+ -+ grub_close (); -+ -+ if (bsd_part == 0xFF) -+ grub_printf (" (hd%d,%d)\n", -+ drive - 0x80, pc_slice); -+ else -+ grub_printf (" (hd%d,%d,%c)\n", -+ drive - 0x80, pc_slice, bsd_part + 'a'); -+ -+ got_file = 1; -+ } -+ } -+ } -+ -+ /* We want to ignore any error here. */ -+ errnum = ERR_NONE; -+ } -+ -+ /* next_partition always sets ERRNUM in the last call, so clear -+ it. */ -+ errnum = ERR_NONE; -+ } -+ -+ saved_drive = tmp_drive; -+ saved_partition = tmp_partition; -+ -+ if (got_file) -+ { -+ errnum = ERR_NONE; -+ return 0; -+ } -+ -+ errnum = ERR_FILE_NOT_FOUND; -+ return 1; -+} -+ -+static struct builtin builtin_find = -+{ -+ "find", -+ find_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "find FILENAME", -+ "Search for the filename FILENAME in all of partitions and print the list of" -+ " the devices which contain the file." -+}; -+ -+ -+/* fstest */ -+static int -+fstest_func (char *arg, int flags) -+{ -+ if (disk_read_hook) -+ { -+ disk_read_hook = NULL; -+ printf (" Filesystem tracing is now off\n"); -+ } -+ else -+ { -+ disk_read_hook = disk_read_print_func; -+ printf (" Filesystem tracing is now on\n"); -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_fstest = -+{ -+ "fstest", -+ fstest_func, -+ BUILTIN_CMDLINE, -+ "fstest", -+ "Toggle filesystem test mode." -+}; -+ -+ -+/* geometry */ -+static int -+geometry_func (char *arg, int flags) -+{ -+ struct geometry geom; -+ char *msg; -+ char *device = arg; -+#ifdef GRUB_UTIL -+ char *ptr; -+#endif -+ -+ /* Get the device number. */ -+ set_device (device); -+ if (errnum) -+ return 1; -+ -+ /* Check for the geometry. */ -+ if (get_diskinfo (current_drive, &geom)) -+ { -+ errnum = ERR_NO_DISK; -+ return 1; -+ } -+ -+ /* Attempt to read the first sector, because some BIOSes turns out not -+ to support LBA even though they set the bit 0 in the support -+ bitmap, only after reading something actually. */ -+ if (biosdisk (BIOSDISK_READ, current_drive, &geom, 0, 1, SCRATCHSEG)) -+ { -+ errnum = ERR_READ; -+ return 1; -+ } -+ -+#ifdef GRUB_UTIL -+ ptr = skip_to (0, device); -+ if (*ptr) -+ { -+ char *cylinder, *head, *sector, *total_sector; -+ int num_cylinder, num_head, num_sector, num_total_sector; -+ -+ cylinder = ptr; -+ head = skip_to (0, cylinder); -+ sector = skip_to (0, head); -+ total_sector = skip_to (0, sector); -+ if (! safe_parse_maxint (&cylinder, &num_cylinder) -+ || ! safe_parse_maxint (&head, &num_head) -+ || ! safe_parse_maxint (§or, &num_sector)) -+ return 1; -+ -+ disks[current_drive].cylinders = num_cylinder; -+ disks[current_drive].heads = num_head; -+ disks[current_drive].sectors = num_sector; -+ -+ if (safe_parse_maxint (&total_sector, &num_total_sector)) -+ disks[current_drive].total_sectors = num_total_sector; -+ else -+ disks[current_drive].total_sectors -+ = num_cylinder * num_head * num_sector; -+ errnum = 0; -+ -+ geom = disks[current_drive]; -+ buf_drive = -1; -+ } -+#endif /* GRUB_UTIL */ -+ -+#ifdef GRUB_UTIL -+ msg = device_map[current_drive]; -+#else -+ if (geom.flags & BIOSDISK_FLAG_LBA_EXTENSION) -+ msg = "LBA"; -+ else -+ msg = "CHS"; -+#endif -+ -+ grub_printf ("drive 0x%x: C/H/S = %d/%d/%d, " -+ "The number of sectors = %d, %s\n", -+ current_drive, -+ geom.cylinders, geom.heads, geom.sectors, -+ geom.total_sectors, msg); -+ real_open_partition (1); -+ -+ return 0; -+} -+ -+static struct builtin builtin_geometry = -+{ -+ "geometry", -+ geometry_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "geometry DRIVE [CYLINDER HEAD SECTOR [TOTAL_SECTOR]]", -+ "Print the information for a drive DRIVE. In the grub shell, you can" -+ " set the geometry of the drive arbitrarily. The number of the cylinders," -+ " the one of the heads, the one of the sectors and the one of the total" -+ " sectors are set to CYLINDER, HEAD, SECTOR and TOTAL_SECTOR," -+ " respectively. If you omit TOTAL_SECTOR, then it will be calculated based" -+ " on the C/H/S values automatically." -+}; -+ -+ -+/* halt */ -+static int -+halt_func (char *arg, int flags) -+{ -+ int no_apm; -+ -+ no_apm = (grub_memcmp (arg, "--no-apm", 8) == 0); -+ grub_halt (no_apm); -+ -+ /* Never reach here. */ -+ return 1; -+} -+ -+static struct builtin builtin_halt = -+{ -+ "halt", -+ halt_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "halt [--no-apm]", -+ "Halt your system. If APM is avaiable on it, turn off the power using" -+ " the APM BIOS, unless you specify the option `--no-apm'." -+}; -+ -+ -+/* help */ -+#define MAX_SHORT_DOC_LEN 39 -+#define MAX_LONG_DOC_LEN 66 -+ -+static int -+help_func (char *arg, int flags) -+{ -+ int all = 0; -+ -+ if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0) -+ { -+ all = 1; -+ arg = skip_to (0, arg); -+ } -+ -+ if (! *arg) -+ { -+ /* Invoked with no argument. Print the list of the short docs. */ -+ struct builtin **builtin; -+ int left = 1; -+ -+ for (builtin = builtin_table; *builtin != 0; builtin++) -+ { -+ int len; -+ int i; -+ -+ /* If this cannot be used in the command-line interface, -+ skip this. */ -+ if (! ((*builtin)->flags & BUILTIN_CMDLINE)) -+ continue; -+ -+ /* If this doesn't need to be listed automatically and "--all" -+ is not specified, skip this. */ -+ if (! all && ! ((*builtin)->flags & BUILTIN_HELP_LIST)) -+ continue; -+ -+ len = grub_strlen ((*builtin)->short_doc); -+ /* If the length of SHORT_DOC is too long, truncate it. */ -+ if (len > MAX_SHORT_DOC_LEN - 1) -+ len = MAX_SHORT_DOC_LEN - 1; -+ -+ for (i = 0; i < len; i++) -+ grub_putchar ((*builtin)->short_doc[i]); -+ -+ for (; i < MAX_SHORT_DOC_LEN; i++) -+ grub_putchar (' '); -+ -+ if (! left) -+ grub_putchar ('\n'); -+ -+ left = ! left; -+ } -+ -+ /* If the last entry was at the left column, no newline was printed -+ at the end. */ -+ if (! left) -+ grub_putchar ('\n'); -+ } -+ else -+ { -+ /* Invoked with one or more patterns. */ -+ do -+ { -+ struct builtin **builtin; -+ char *next_arg; -+ -+ /* Get the next argument. */ -+ next_arg = skip_to (0, arg); -+ -+ /* Terminate ARG. */ -+ nul_terminate (arg); -+ -+ for (builtin = builtin_table; *builtin; builtin++) -+ { -+ /* Skip this if this is only for the configuration file. */ -+ if (! ((*builtin)->flags & BUILTIN_CMDLINE)) -+ continue; -+ -+ if (substring (arg, (*builtin)->name) < 1) -+ { -+ char *doc = (*builtin)->long_doc; -+ -+ /* At first, print the name and the short doc. */ -+ grub_printf ("%s: %s\n", -+ (*builtin)->name, (*builtin)->short_doc); -+ -+ /* Print the long doc. */ -+ while (*doc) -+ { -+ int len = grub_strlen (doc); -+ int i; -+ -+ /* If LEN is too long, fold DOC. */ -+ if (len > MAX_LONG_DOC_LEN) -+ { -+ /* Fold this line at the position of a space. */ -+ for (len = MAX_LONG_DOC_LEN; len > 0; len--) -+ if (doc[len - 1] == ' ') -+ break; -+ } -+ -+ grub_printf (" "); -+ for (i = 0; i < len; i++) -+ grub_putchar (*doc++); -+ grub_putchar ('\n'); -+ } -+ } -+ } -+ -+ arg = next_arg; -+ } -+ while (*arg); -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_help = -+{ -+ "help", -+ help_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "help [--all] [PATTERN ...]", -+ "Display helpful information about builtin commands. Not all commands" -+ " aren't shown without the option `--all'." -+}; -+ -+ -+/* hiddenmenu */ -+static int -+hiddenmenu_func (char *arg, int flags) -+{ -+ show_menu = 0; -+ return 0; -+} -+ -+static struct builtin builtin_hiddenmenu = -+{ -+ "hiddenmenu", -+ hiddenmenu_func, -+ BUILTIN_MENU, -+#if 0 -+ "hiddenmenu", -+ "Hide the menu." -+#endif -+}; -+ -+ -+/* hide */ -+static int -+hide_func (char *arg, int flags) -+{ -+ if (! set_device (arg)) -+ return 1; -+ -+ if (! set_partition_hidden_flag (1)) -+ return 1; -+ -+ return 0; -+} -+ -+static struct builtin builtin_hide = -+{ -+ "hide", -+ hide_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "hide PARTITION", -+ "Hide PARTITION by setting the "hidden" bit in" -+ " its partition type code." -+}; -+ -+ -+#ifdef SUPPORT_NETBOOT -+/* ifconfig */ -+static int -+ifconfig_func (char *arg, int flags) -+{ -+ char *svr = 0, *ip = 0, *gw = 0, *sm = 0; -+ -+ if (! eth_probe ()) -+ { -+ grub_printf ("No ethernet card found.\n"); -+ errnum = ERR_DEV_VALUES; -+ return 1; -+ } -+ -+ while (*arg) -+ { -+ if (! grub_memcmp ("--server=", arg, sizeof ("--server=") - 1)) -+ svr = arg + sizeof("--server=") - 1; -+ else if (! grub_memcmp ("--address=", arg, sizeof ("--address=") - 1)) -+ ip = arg + sizeof ("--address=") - 1; -+ else if (! grub_memcmp ("--gateway=", arg, sizeof ("--gateway=") - 1)) -+ gw = arg + sizeof ("--gateway=") - 1; -+ else if (! grub_memcmp ("--mask=", arg, sizeof("--mask=") - 1)) -+ sm = arg + sizeof ("--mask=") - 1; -+ else -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ arg = skip_to (0, arg); -+ } -+ -+ if (! ifconfig (ip, sm, gw, svr)) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ print_network_configuration (); -+ return 0; -+} -+ -+static struct builtin builtin_ifconfig = -+{ -+ "ifconfig", -+ ifconfig_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "ifconfig [--address=IP] [--gateway=IP] [--mask=MASK] [--server=IP]", -+ "Configure the IP address, the netmask, the gateway and the server" -+ " address or print current network configuration." -+}; -+#endif /* SUPPORT_NETBOOT */ -+ -+ -+/* impsprobe */ -+static int -+impsprobe_func (char *arg, int flags) -+{ -+#ifdef GRUB_UTIL -+ /* In the grub shell, we cannot probe IMPS. */ -+ errnum = ERR_UNRECOGNIZED; -+ return 1; -+#else /* ! GRUB_UTIL */ -+ if (!imps_probe ()) -+ printf (" No MPS information found or probe failed\n"); -+ -+ return 0; -+#endif /* ! GRUB_UTIL */ -+} -+ -+static struct builtin builtin_impsprobe = -+{ -+ "impsprobe", -+ impsprobe_func, -+ BUILTIN_CMDLINE, -+ "impsprobe", -+ "Probe the Intel Multiprocessor Specification 1.1 or 1.4" -+ " configuration table and boot the various CPUs which are found into" -+ " a tight loop." -+}; -+ -+ -+/* initrd */ -+static int -+initrd_func (char *arg, int flags) -+{ -+ switch (kernel_type) -+ { -+ case KERNEL_TYPE_LINUX: -+ case KERNEL_TYPE_BIG_LINUX: -+ if (! load_initrd (arg)) -+ return 1; -+ break; -+ -+ default: -+ errnum = ERR_NEED_LX_KERNEL; -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_initrd = -+{ -+ "initrd", -+ initrd_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "initrd FILE [ARG ...]", -+ "Load an initial ramdisk FILE for a Linux format boot image and set the" -+ " appropriate parameters in the Linux setup area in memory." -+}; -+ -+ -+/* install */ -+static int -+install_func (char *arg, int flags) -+{ -+ char *stage1_file, *dest_dev, *file, *addr; -+ char *stage1_buffer = (char *) RAW_ADDR (0x100000); -+ char *stage2_buffer = stage1_buffer + SECTOR_SIZE; -+ char *old_sect = stage2_buffer + SECTOR_SIZE; -+ char *stage2_first_buffer = old_sect + SECTOR_SIZE; -+ char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE; -+ /* XXX: Probably SECTOR_SIZE is reasonable. */ -+ char *config_filename = stage2_second_buffer + SECTOR_SIZE; -+ char *dummy = config_filename + SECTOR_SIZE; -+ int new_drive = GRUB_INVALID_DRIVE; -+ int dest_drive, dest_partition, dest_sector; -+ int src_drive, src_partition, src_part_start; -+ int i; -+ struct geometry dest_geom, src_geom; -+ int saved_sector; -+ int stage2_first_sector, stage2_second_sector; -+ char *ptr; -+ int installaddr, installlist; -+ /* Point to the location of the name of a configuration file in Stage 2. */ -+ char *config_file_location; -+ /* If FILE is a Stage 1.5? */ -+ int is_stage1_5 = 0; -+ /* Must call grub_close? */ -+ int is_open = 0; -+ /* If LBA is forced? */ -+ int is_force_lba = 0; -+ /* Was the last sector full? */ -+ int last_length = SECTOR_SIZE; -+ -+#ifdef GRUB_UTIL -+ /* If the Stage 2 is in a partition mounted by an OS, this will store -+ the filename under the OS. */ -+ char *stage2_os_file = 0; -+#endif /* GRUB_UTIL */ -+ -+ auto void disk_read_savesect_func (int sector, int offset, int length); -+ auto void disk_read_blocklist_func (int sector, int offset, int length); -+ -+ /* Save the first sector of Stage2 in STAGE2_SECT. */ -+ auto void disk_read_savesect_func (int sector, int offset, int length) -+ { -+ if (debug) -+ printf ("[%d]", sector); -+ -+ /* ReiserFS has files which sometimes contain data not aligned -+ on sector boundaries. Returning an error is better than -+ silently failing. */ -+ if (offset != 0 || length != SECTOR_SIZE) -+ errnum = ERR_UNALIGNED; -+ -+ saved_sector = sector; -+ } -+ -+ /* Write SECTOR to INSTALLLIST, and update INSTALLADDR and -+ INSTALLSECT. */ -+ auto void disk_read_blocklist_func (int sector, int offset, int length) -+ { -+ if (debug) -+ printf("[%d]", sector); -+ -+ if (offset != 0 || last_length != SECTOR_SIZE) -+ { -+ /* We found a non-sector-aligned data block. */ -+ errnum = ERR_UNALIGNED; -+ return; -+ } -+ -+ last_length = length; -+ -+ if (*((unsigned long *) (installlist - 4)) -+ + *((unsigned short *) installlist) != sector -+ || installlist == (int) stage2_first_buffer + SECTOR_SIZE + 4) -+ { -+ installlist -= 8; -+ -+ if (*((unsigned long *) (installlist - 8))) -+ errnum = ERR_WONT_FIT; -+ else -+ { -+ *((unsigned short *) (installlist + 2)) = (installaddr >> 4); -+ *((unsigned long *) (installlist - 4)) = sector; -+ } -+ } -+ -+ *((unsigned short *) installlist) += 1; -+ installaddr += 512; -+ } -+ -+ /* First, check the GNU-style long option. */ -+ while (1) -+ { -+ if (grub_memcmp ("--force-lba", arg, sizeof ("--force-lba") - 1) == 0) -+ { -+ is_force_lba = 1; -+ arg = skip_to (0, arg); -+ } -+#ifdef GRUB_UTIL -+ else if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0) -+ { -+ stage2_os_file = arg + sizeof ("--stage2=") - 1; -+ arg = skip_to (0, arg); -+ nul_terminate (stage2_os_file); -+ } -+#endif /* GRUB_UTIL */ -+ else -+ break; -+ } -+ -+ stage1_file = arg; -+ dest_dev = skip_to (0, stage1_file); -+ if (*dest_dev == 'd') -+ { -+ new_drive = 0; -+ dest_dev = skip_to (0, dest_dev); -+ } -+ file = skip_to (0, dest_dev); -+ addr = skip_to (0, file); -+ -+ /* Get the installation address. */ -+ if (! safe_parse_maxint (&addr, &installaddr)) -+ { -+ /* ADDR is not specified. */ -+ installaddr = 0; -+ ptr = addr; -+ errnum = 0; -+ } -+ else -+ ptr = skip_to (0, addr); -+ -+#ifndef NO_DECOMPRESSION -+ /* Do not decompress Stage 1 or Stage 2. */ -+ no_decompression = 1; -+#endif -+ -+ /* Read Stage 1. */ -+ is_open = grub_open (stage1_file); -+ if (! is_open -+ || ! grub_read (stage1_buffer, SECTOR_SIZE) == SECTOR_SIZE) -+ goto fail; -+ -+ /* Read the old sector from DEST_DEV. */ -+ if (! set_device (dest_dev) -+ || ! open_partition () -+ || ! devread (0, 0, SECTOR_SIZE, old_sect)) -+ goto fail; -+ -+ /* Store the information for the destination device. */ -+ dest_drive = current_drive; -+ dest_partition = current_partition; -+ dest_geom = buf_geom; -+ dest_sector = part_start; -+ -+ /* Copy the possible DOS BPB, 59 bytes at byte offset 3. */ -+ grub_memmove (stage1_buffer + BOOTSEC_BPB_OFFSET, -+ old_sect + BOOTSEC_BPB_OFFSET, -+ BOOTSEC_BPB_LENGTH); -+ -+ /* If for a hard disk, copy the possible MBR/extended part table. */ -+ if (dest_drive & 0x80) -+ grub_memmove (stage1_buffer + STAGE1_WINDOWS_NT_MAGIC, -+ old_sect + STAGE1_WINDOWS_NT_MAGIC, -+ STAGE1_PARTEND - STAGE1_WINDOWS_NT_MAGIC); -+ -+ /* Check for the version and the signature of Stage 1. */ -+ if (*((short *)(stage1_buffer + STAGE1_VER_MAJ_OFFS)) != COMPAT_VERSION -+ || (*((unsigned short *) (stage1_buffer + BOOTSEC_SIG_OFFSET)) -+ != BOOTSEC_SIGNATURE)) -+ { -+ errnum = ERR_BAD_VERSION; -+ goto fail; -+ } -+ -+ /* This below is not true any longer. But should we leave this alone? */ -+ -+ /* If DEST_DRIVE is a floppy, Stage 2 must have the iteration probe -+ routine. */ -+ if (! (dest_drive & 0x80) -+ && (*((unsigned char *) (stage1_buffer + BOOTSEC_PART_OFFSET)) == 0x80 -+ || stage1_buffer[BOOTSEC_PART_OFFSET] == 0)) -+ { -+ errnum = ERR_BAD_VERSION; -+ goto fail; -+ } -+ -+ grub_close (); -+ -+ /* Open Stage 2. */ -+ is_open = grub_open (file); -+ if (! is_open) -+ goto fail; -+ -+ src_drive = current_drive; -+ src_partition = current_partition; -+ src_part_start = part_start; -+ src_geom = buf_geom; -+ -+ if (! new_drive) -+ new_drive = src_drive; -+ else if (src_drive != dest_drive) -+ grub_printf ("Warning: the option `d' was not used, but the Stage 1 will" -+ " be installed on a\ndifferent drive than the drive where" -+ " the Stage 2 resides.\n"); -+ -+ /* Set the boot drive. */ -+ *((unsigned char *) (stage1_buffer + STAGE1_BOOT_DRIVE)) = new_drive; -+ -+ /* Set the "force LBA" flag. */ -+ *((unsigned char *) (stage1_buffer + STAGE1_FORCE_LBA)) = is_force_lba; -+ -+ /* If DEST_DRIVE is a hard disk, enable the workaround, which is -+ for buggy BIOSes which don't pass boot drive correctly. Instead, -+ they pass 0x00 or 0x01 even when booted from 0x80. */ -+ if (dest_drive & BIOS_FLAG_FIXED_DISK) -+ /* Replace the jmp (2 bytes) with double nop's. */ -+ *((unsigned short *) (stage1_buffer + STAGE1_BOOT_DRIVE_CHECK)) -+ = 0x9090; -+ -+ /* Read the first sector of Stage 2. */ -+ disk_read_hook = disk_read_savesect_func; -+ if (grub_read (stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE) -+ goto fail; -+ -+ stage2_first_sector = saved_sector; -+ -+ /* Read the second sector of Stage 2. */ -+ if (grub_read (stage2_second_buffer, SECTOR_SIZE) != SECTOR_SIZE) -+ goto fail; -+ -+ stage2_second_sector = saved_sector; -+ -+ /* Check for the version of Stage 2. */ -+ if (*((short *) (stage2_second_buffer + STAGE2_VER_MAJ_OFFS)) -+ != COMPAT_VERSION) -+ { -+ errnum = ERR_BAD_VERSION; -+ goto fail; -+ } -+ -+ /* Check for the Stage 2 id. */ -+ if (stage2_second_buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2) -+ is_stage1_5 = 1; -+ -+ /* If INSTALLADDR is not specified explicitly in the command-line, -+ determine it by the Stage 2 id. */ -+ if (! installaddr) -+ { -+ if (! is_stage1_5) -+ /* Stage 2. */ -+ installaddr = 0x8000; -+ else -+ /* Stage 1.5. */ -+ installaddr = 0x2000; -+ } -+ -+ *((unsigned long *) (stage1_buffer + STAGE1_STAGE2_SECTOR)) -+ = stage2_first_sector; -+ *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_ADDRESS)) -+ = installaddr; -+ *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_SEGMENT)) -+ = installaddr >> 4; -+ -+ i = (int) stage2_first_buffer + SECTOR_SIZE - 4; -+ while (*((unsigned long *) i)) -+ { -+ if (i < (int) stage2_first_buffer -+ || (*((int *) (i - 4)) & 0x80000000) -+ || *((unsigned short *) i) >= 0xA00 -+ || *((short *) (i + 2)) == 0) -+ { -+ errnum = ERR_BAD_VERSION; -+ goto fail; -+ } -+ -+ *((int *) i) = 0; -+ *((int *) (i - 4)) = 0; -+ i -= 8; -+ } -+ -+ installlist = (int) stage2_first_buffer + SECTOR_SIZE + 4; -+ installaddr += SECTOR_SIZE; -+ -+ /* Read the whole of Stage2 except for the first sector. */ -+ grub_seek (SECTOR_SIZE); -+ -+ disk_read_hook = disk_read_blocklist_func; -+ if (! grub_read (dummy, -1)) -+ goto fail; -+ -+ disk_read_hook = 0; -+ -+ /* Find a string for the configuration filename. */ -+ config_file_location = stage2_second_buffer + STAGE2_VER_STR_OFFS; -+ while (*(config_file_location++)) -+ ; -+ -+ /* Set the "force LBA" flag for Stage2. */ -+ *((unsigned char *) (stage2_second_buffer + STAGE2_FORCE_LBA)) -+ = is_force_lba; -+ -+ if (*ptr == 'p') -+ { -+ *((long *) (stage2_second_buffer + STAGE2_INSTALLPART)) -+ = src_partition; -+ if (is_stage1_5) -+ { -+ /* Reset the device information in FILE if it is a Stage 1.5. */ -+ unsigned long device = 0xFFFFFFFF; -+ -+ grub_memmove (config_file_location, (char *) &device, -+ sizeof (device)); -+ } -+ -+ ptr = skip_to (0, ptr); -+ } -+ -+ if (*ptr) -+ { -+ grub_strcpy (config_filename, ptr); -+ nul_terminate (config_filename); -+ -+ if (! is_stage1_5) -+ /* If it is a Stage 2, just copy PTR to CONFIG_FILE_LOCATION. */ -+ grub_strcpy (config_file_location, ptr); -+ else -+ { -+ char *real_config; -+ unsigned long device; -+ -+ /* Translate the external device syntax to the internal device -+ syntax. */ -+ if (! (real_config = set_device (ptr))) -+ { -+ /* The Stage 2 PTR does not contain the device name, so -+ use the root device instead. */ -+ errnum = ERR_NONE; -+ current_drive = saved_drive; -+ current_partition = saved_partition; -+ real_config = ptr; -+ } -+ -+ if (current_drive == src_drive) -+ { -+ /* If the drive where the Stage 2 resides is the same as -+ the one where the Stage 1.5 resides, do not embed the -+ drive number. */ -+ current_drive = GRUB_INVALID_DRIVE; -+ } -+ -+ device = (current_drive << 24) | current_partition; -+ grub_memmove (config_file_location, (char *) &device, -+ sizeof (device)); -+ grub_strcpy (config_file_location + sizeof (device), -+ real_config); -+ } -+ -+ /* If a Stage 1.5 is used, then we need to modify the Stage2. */ -+ if (is_stage1_5) -+ { -+ char *real_config_filename = skip_to (0, ptr); -+ -+ is_open = grub_open (config_filename); -+ if (! is_open) -+ goto fail; -+ -+ /* Skip the first sector. */ -+ grub_seek (SECTOR_SIZE); -+ -+ disk_read_hook = disk_read_savesect_func; -+ if (grub_read (stage2_buffer, SECTOR_SIZE) != SECTOR_SIZE) -+ goto fail; -+ -+ disk_read_hook = 0; -+ grub_close (); -+ is_open = 0; -+ -+ /* Sanity check. */ -+ if (*(stage2_buffer + STAGE2_STAGE2_ID) != STAGE2_ID_STAGE2) -+ { -+ errnum = ERR_BAD_VERSION; -+ goto fail; -+ } -+ -+ /* Set the "force LBA" flag for Stage2. */ -+ *(stage2_buffer + STAGE2_FORCE_LBA) = is_force_lba; -+ -+ /* If REAL_CONFIG_FILENAME is specified, copy it to the Stage2. */ -+ if (*real_config_filename) -+ { -+ /* Specified */ -+ char *location; -+ -+ /* Find a string for the configuration filename. */ -+ location = stage2_buffer + STAGE2_VER_STR_OFFS; -+ while (*(location++)) -+ ; -+ -+ /* Copy the name. */ -+ grub_strcpy (location, real_config_filename); -+ } -+ -+ /* Write it to the disk. */ -+ buf_track = -1; -+ -+#ifdef GRUB_UTIL -+ /* In the grub shell, access the Stage 2 via the OS filesystem -+ service, if possible. */ -+ if (stage2_os_file) -+ { -+ FILE *fp; -+ -+ fp = fopen (stage2_os_file, "r+"); -+ if (! fp) -+ { -+ errnum = ERR_FILE_NOT_FOUND; -+ goto fail; -+ } -+ -+ if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0) -+ { -+ fclose (fp); -+ errnum = ERR_BAD_VERSION; -+ goto fail; -+ } -+ -+ if (fwrite (stage2_buffer, 1, SECTOR_SIZE, fp) -+ != SECTOR_SIZE) -+ { -+ fclose (fp); -+ errnum = ERR_WRITE; -+ goto fail; -+ } -+ -+ fclose (fp); -+ } -+ else -+#endif /* GRUB_UTIL */ -+ { -+ if (! devwrite (saved_sector - part_start, 1, stage2_buffer)) -+ goto fail; -+ } -+ } -+ } -+ -+ /* Clear the cache. */ -+ buf_track = -1; -+ -+ /* Write the modified sectors of Stage2 to the disk. */ -+#ifdef GRUB_UTIL -+ if (! is_stage1_5 && stage2_os_file) -+ { -+ FILE *fp; -+ -+ fp = fopen (stage2_os_file, "r+"); -+ if (! fp) -+ { -+ errnum = ERR_FILE_NOT_FOUND; -+ goto fail; -+ } -+ -+ if (fwrite (stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) -+ { -+ fclose (fp); -+ errnum = ERR_WRITE; -+ goto fail; -+ } -+ -+ if (fwrite (stage2_second_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) -+ { -+ fclose (fp); -+ errnum = ERR_WRITE; -+ goto fail; -+ } -+ -+ fclose (fp); -+ } -+ else -+#endif /* GRUB_UTIL */ -+ { -+ /* The first. */ -+ current_drive = src_drive; -+ current_partition = src_partition; -+ -+ if (! open_partition ()) -+ goto fail; -+ -+ if (! devwrite (stage2_first_sector - src_part_start, 1, -+ stage2_first_buffer)) -+ goto fail; -+ -+ if (! devwrite (stage2_second_sector - src_part_start, 1, -+ stage2_second_buffer)) -+ goto fail; -+ } -+ -+ /* Write the modified sector of Stage 1 to the disk. */ -+ current_drive = dest_drive; -+ current_partition = dest_partition; -+ if (! open_partition ()) -+ goto fail; -+ -+ devwrite (0, 1, stage1_buffer); -+ -+ fail: -+ if (is_open) -+ grub_close (); -+ -+ disk_read_hook = 0; -+ -+#ifndef NO_DECOMPRESSION -+ no_decompression = 0; -+#endif -+ -+ return errnum; -+} -+ -+static struct builtin builtin_install = -+{ -+ "install", -+ install_func, -+ BUILTIN_CMDLINE, -+ "install [--stage2=STAGE2_FILE] [--force-lba] STAGE1 [d] DEVICE STAGE2 [ADDR] [p] [CONFIG_FILE] [REAL_CONFIG_FILE]", -+ "Install STAGE1 on DEVICE, and install a blocklist for loading STAGE2" -+ " as a Stage 2. If the option `d' is present, the Stage 1 will always" -+ " look for the disk where STAGE2 was installed, rather than using" -+ " the booting drive. The Stage 2 will be loaded at address ADDR, which" -+ " will be determined automatically if you don't specify it. If" -+ " the option `p' or CONFIG_FILE is present, then the first block" -+ " of Stage 2 is patched with new values of the partition and name" -+ " of the configuration file used by the true Stage 2 (for a Stage 1.5," -+ " this is the name of the true Stage 2) at boot time. If STAGE2 is a Stage" -+ " 1.5 and REAL_CONFIG_FILE is present, then the Stage 2 CONFIG_FILE is" -+ " patched with the configuration filename REAL_CONFIG_FILE." -+ " If the option `--force-lba' is specified, disable some sanity checks" -+ " for LBA mode. If the option `--stage2' is specified, rewrite the Stage" -+ " 2 via your OS's filesystem instead of the raw device." -+}; -+ -+ -+/* ioprobe */ -+static int -+ioprobe_func (char *arg, int flags) -+{ -+#ifdef GRUB_UTIL -+ -+ errnum = ERR_UNRECOGNIZED; -+ return 1; -+ -+#else /* ! GRUB_UTIL */ -+ -+ unsigned short *port; -+ -+ /* Get the drive number. */ -+ set_device (arg); -+ if (errnum) -+ return 1; -+ -+ /* Clean out IO_MAP. */ -+ grub_memset ((char *) io_map, 0, IO_MAP_SIZE * sizeof (unsigned short)); -+ -+ /* Track the int13 handler. */ -+ track_int13 (current_drive); -+ -+ /* Print out the result. */ -+ for (port = io_map; *port != 0; port++) -+ grub_printf (" 0x%x", (unsigned int) *port); -+ -+ return 0; -+ -+#endif /* ! GRUB_UTIL */ -+} -+ -+static struct builtin builtin_ioprobe = -+{ -+ "ioprobe", -+ ioprobe_func, -+ BUILTIN_CMDLINE, -+ "ioprobe DRIVE", -+ "Probe I/O ports used for the drive DRIVE." -+}; -+ -+ -+/* kernel */ -+static int -+kernel_func (char *arg, int flags) -+{ -+ int len; -+ kernel_t suggested_type = KERNEL_TYPE_NONE; -+ unsigned long load_flags = 0; -+ -+#ifndef AUTO_LINUX_MEM_OPT -+ load_flags |= KERNEL_LOAD_NO_MEM_OPTION; -+#endif -+ -+ /* Deal with GNU-style long options. */ -+ while (1) -+ { -+ /* If the option `--type=TYPE' is specified, convert the string to -+ a kernel type. */ -+ if (grub_memcmp (arg, "--type=", 7) == 0) -+ { -+ arg += 7; -+ -+ if (grub_memcmp (arg, "netbsd", 6) == 0) -+ suggested_type = KERNEL_TYPE_NETBSD; -+ else if (grub_memcmp (arg, "freebsd", 7) == 0) -+ suggested_type = KERNEL_TYPE_FREEBSD; -+ else if (grub_memcmp (arg, "openbsd", 7) == 0) -+ /* XXX: For now, OpenBSD is identical to NetBSD, from GRUB's -+ point of view. */ -+ suggested_type = KERNEL_TYPE_NETBSD; -+ else if (grub_memcmp (arg, "linux", 5) == 0) -+ suggested_type = KERNEL_TYPE_LINUX; -+ else if (grub_memcmp (arg, "biglinux", 8) == 0) -+ suggested_type = KERNEL_TYPE_BIG_LINUX; -+ else if (grub_memcmp (arg, "multiboot", 9) == 0) -+ suggested_type = KERNEL_TYPE_MULTIBOOT; -+ else -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ } -+ /* If the `--no-mem-option' is specified, don't pass a Linux's mem -+ option automatically. If the kernel is another type, this flag -+ has no effect. */ -+ else if (grub_memcmp (arg, "--no-mem-option", 15) == 0) -+ load_flags |= KERNEL_LOAD_NO_MEM_OPTION; -+ else -+ break; -+ -+ /* Try the next. */ -+ arg = skip_to (0, arg); -+ } -+ -+ len = grub_strlen (arg); -+ -+ /* Reset MB_CMDLINE. */ -+ mb_cmdline = (char *) MB_CMDLINE_BUF; -+ if (len + 1 > MB_CMDLINE_BUFLEN) -+ { -+ errnum = ERR_WONT_FIT; -+ return 1; -+ } -+ -+ /* Copy the command-line to MB_CMDLINE. */ -+ grub_memmove (mb_cmdline, arg, len + 1); -+ kernel_type = load_image (arg, mb_cmdline, suggested_type, load_flags); -+ if (kernel_type == KERNEL_TYPE_NONE) -+ return 1; -+ -+ mb_cmdline += len + 1; -+ return 0; -+} -+ -+static struct builtin builtin_kernel = -+{ -+ "kernel", -+ kernel_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "kernel [--no-mem-option] [--type=TYPE] FILE [ARG ...]", -+ "Attempt to load the primary boot image from FILE. The rest of the" -+ " line is passed verbatim as the "kernel command line". Any modules" -+ " must be reloaded after using this command. The option --type is used" -+ " to suggest what type of kernel to be loaded. TYPE must be either of" -+ " "netbsd", "freebsd", "openbsd", "linux", "biglinux" and" -+ " "multiboot". The option --no-mem-option tells GRUB not to pass a" -+ " Linux's mem option automatically." -+}; -+ -+ -+/* lock */ -+static int -+lock_func (char *arg, int flags) -+{ -+ if (! auth && password) -+ { -+ errnum = ERR_PRIVILEGED; -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_lock = -+{ -+ "lock", -+ lock_func, -+ BUILTIN_CMDLINE, -+ "lock", -+ "Break a command execution unless the user is authenticated." -+}; -+ -+ -+/* makeactive */ -+static int -+makeactive_func (char *arg, int flags) -+{ -+ if (! make_saved_active ()) -+ return 1; -+ -+ return 0; -+} -+ -+static struct builtin builtin_makeactive = -+{ -+ "makeactive", -+ makeactive_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "makeactive", -+ "Set the active partition on the root disk to GRUB's root device." -+ " This command is limited to _primary_ PC partitions on a hard disk." -+}; -+ -+ -+/* map */ -+/* Map FROM_DRIVE to TO_DRIVE. */ -+static int -+map_func (char *arg, int flags) -+{ -+ char *to_drive; -+ char *from_drive; -+ unsigned long to, from; -+ int i; -+ -+ to_drive = arg; -+ from_drive = skip_to (0, arg); -+ -+ /* Get the drive number for TO_DRIVE. */ -+ set_device (to_drive); -+ if (errnum) -+ return 1; -+ to = current_drive; -+ -+ /* Get the drive number for FROM_DRIVE. */ -+ set_device (from_drive); -+ if (errnum) -+ return 1; -+ from = current_drive; -+ -+ /* Search for an empty slot in BIOS_DRIVE_MAP. */ -+ for (i = 0; i < DRIVE_MAP_SIZE; i++) -+ { -+ /* Perhaps the user wants to override the map. */ -+ if ((bios_drive_map[i] & 0xff) == from) -+ break; -+ -+ if (! bios_drive_map[i]) -+ break; -+ } -+ -+ if (i == DRIVE_MAP_SIZE) -+ { -+ errnum = ERR_WONT_FIT; -+ return 1; -+ } -+ -+ if (to == from) -+ /* If TO is equal to FROM, delete the entry. */ -+ grub_memmove ((char *) &bios_drive_map[i], (char *) &bios_drive_map[i + 1], -+ sizeof (unsigned short) * (DRIVE_MAP_SIZE - i)); -+ else -+ bios_drive_map[i] = from | (to << 8); -+ -+ return 0; -+} -+ -+static struct builtin builtin_map = -+{ -+ "map", -+ map_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "map TO_DRIVE FROM_DRIVE", -+ "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary" -+ " when you chain-load some operating systems, such as DOS, if such an" -+ " OS resides at a non-first drive." -+}; -+ -+ -+#ifdef USE_MD5_PASSWORDS -+/* md5crypt */ -+static int -+md5crypt_func (char *arg, int flags) -+{ -+ char crypted[36]; -+ char key[32]; -+ unsigned int seed; -+ int i; -+ const char *const seedchars = -+ "./0123456789ABCDEFGHIJKLMNOPQRST" -+ "UVWXYZabcdefghijklmnopqrstuvwxyz"; -+ -+ /* First create a salt. */ -+ -+ /* The magical prefix. */ -+ grub_memset (crypted, 0, sizeof (crypted)); -+ grub_memmove (crypted, "$1$", 3); -+ -+ /* Create the length of a salt. */ -+ seed = currticks (); -+ -+ /* Generate a salt. */ -+ for (i = 0; i < 8 && seed; i++) -+ { -+ /* FIXME: This should be more random. */ -+ crypted[3 + i] = seedchars[seed & 0x3f]; -+ seed >>= 6; -+ } -+ -+ /* A salt must be terminated with `$', if it is less than 8 chars. */ -+ crypted[3 + i] = '$'; -+ -+#ifdef DEBUG_MD5CRYPT -+ grub_printf ("salt = %s\n", crypted); -+#endif -+ -+ /* Get a password. */ -+ grub_memset (key, 0, sizeof (key)); -+ get_cmdline ("Password: ", key, sizeof (key) - 1, '*', 0); -+ -+ /* Crypt the key. */ -+ make_md5_password (key, crypted); -+ -+ grub_printf ("Encrypted: %s\n", crypted); -+ return 0; -+} -+ -+static struct builtin builtin_md5crypt = -+{ -+ "md5crypt", -+ md5crypt_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "md5crypt", -+ "Generate a password in MD5 format." -+}; -+#endif /* USE_MD5_PASSWORDS */ -+ -+ -+/* module */ -+static int -+module_func (char *arg, int flags) -+{ -+ int len = grub_strlen (arg); -+ -+ switch (kernel_type) -+ { -+ case KERNEL_TYPE_MULTIBOOT: -+ if (mb_cmdline + len + 1 > (char *) MB_CMDLINE_BUF + MB_CMDLINE_BUFLEN) -+ { -+ errnum = ERR_WONT_FIT; -+ return 1; -+ } -+ grub_memmove (mb_cmdline, arg, len + 1); -+ if (! load_module (arg, mb_cmdline)) -+ return 1; -+ mb_cmdline += len + 1; -+ break; -+ -+ case KERNEL_TYPE_LINUX: -+ case KERNEL_TYPE_BIG_LINUX: -+ if (! load_initrd (arg)) -+ return 1; -+ break; -+ -+ default: -+ errnum = ERR_NEED_MB_KERNEL; -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_module = -+{ -+ "module", -+ module_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "module FILE [ARG ...]", -+ "Load a boot module FILE for a Multiboot format boot image (no" -+ " interpretation of the file contents is made, so users of this" -+ " command must know what the kernel in question expects). The" -+ " rest of the line is passed as the "module command line", like" -+ " the `kernel' command." -+}; -+ -+ -+/* modulenounzip */ -+static int -+modulenounzip_func (char *arg, int flags) -+{ -+ int ret; -+ -+#ifndef NO_DECOMPRESSION -+ no_decompression = 1; -+#endif -+ -+ ret = module_func (arg, flags); -+ -+#ifndef NO_DECOMPRESSION -+ no_decompression = 0; -+#endif -+ -+ return ret; -+} -+ -+static struct builtin builtin_modulenounzip = -+{ -+ "modulenounzip", -+ modulenounzip_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "modulenounzip FILE [ARG ...]", -+ "The same as `module', except that automatic decompression is" -+ " disabled." -+}; -+ -+ -+/* pager [on|off] */ -+static int -+pager_func (char *arg, int flags) -+{ -+ /* If ARG is empty, toggle the flag. */ -+ if (! *arg) -+ use_pager = ! use_pager; -+ else if (grub_memcmp (arg, "on", 2) == 0) -+ use_pager = 1; -+ else if (grub_memcmp (arg, "off", 3) == 0) -+ use_pager = 0; -+ else -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ grub_printf (" Internal pager is now %s\n", use_pager ? "on" : "off"); -+ return 0; -+} -+ -+static struct builtin builtin_pager = -+{ -+ "pager", -+ pager_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "pager [FLAG]", -+ "Toggle pager mode with no argument. If FLAG is given and its value" -+ " is `on', turn on the mode. If FLAG is `off', turn off the mode." -+}; -+ -+ -+/* partnew PART TYPE START LEN */ -+static int -+partnew_func (char *arg, int flags) -+{ -+ int new_type, new_start, new_len; -+ int start_cl, start_ch, start_dh; -+ int end_cl, end_ch, end_dh; -+ int entry; -+ char mbr[512]; -+ -+ /* Convert a LBA address to a CHS address in the INT 13 format. */ -+ auto void lba_to_chs (int lba, int *cl, int *ch, int *dh); -+ void lba_to_chs (int lba, int *cl, int *ch, int *dh) -+ { -+ int cylinder, head, sector; -+ -+ sector = lba % buf_geom.sectors + 1; -+ head = (lba / buf_geom.sectors) % buf_geom.heads; -+ cylinder = lba / (buf_geom.sectors * buf_geom.heads); -+ -+ if (cylinder >= buf_geom.cylinders) -+ cylinder = buf_geom.cylinders - 1; -+ -+ *cl = sector | ((cylinder & 0x300) >> 2); -+ *ch = cylinder & 0xFF; -+ *dh = head; -+ } -+ -+ /* Get the drive and the partition. */ -+ if (! set_device (arg)) -+ return 1; -+ -+ /* The drive must be a hard disk. */ -+ if (! (current_drive & 0x80)) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ /* The partition must a primary partition. */ -+ if ((current_partition >> 16) > 3 -+ || (current_partition & 0xFFFF) != 0xFFFF) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ entry = current_partition >> 16; -+ -+ /* Get the new partition type. */ -+ arg = skip_to (0, arg); -+ if (! safe_parse_maxint (&arg, &new_type)) -+ return 1; -+ -+ /* The partition type is unsigned char. */ -+ if (new_type > 0xFF) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ /* Get the new partition start. */ -+ arg = skip_to (0, arg); -+ if (! safe_parse_maxint (&arg, &new_start)) -+ return 1; -+ -+ /* Get the new partition length. */ -+ arg = skip_to (0, arg); -+ if (! safe_parse_maxint (&arg, &new_len)) -+ return 1; -+ -+ /* Read the MBR. */ -+ if (! rawread (current_drive, 0, 0, SECTOR_SIZE, mbr)) -+ return 1; -+ -+ /* Check if the new partition will fit in the disk. */ -+ if (new_start + new_len > buf_geom.total_sectors) -+ { -+ errnum = ERR_GEOM; -+ return 1; -+ } -+ -+ /* Store the partition information in the MBR. */ -+ lba_to_chs (new_start, &start_cl, &start_ch, &start_dh); -+ lba_to_chs (new_start + new_len - 1, &end_cl, &end_ch, &end_dh); -+ -+ PC_SLICE_FLAG (mbr, entry) = 0; -+ PC_SLICE_HEAD (mbr, entry) = start_dh; -+ PC_SLICE_SEC (mbr, entry) = start_cl; -+ PC_SLICE_CYL (mbr, entry) = start_ch; -+ PC_SLICE_TYPE (mbr, entry) = new_type; -+ PC_SLICE_EHEAD (mbr, entry) = end_dh; -+ PC_SLICE_ESEC (mbr, entry) = end_cl; -+ PC_SLICE_ECYL (mbr, entry) = end_ch; -+ PC_SLICE_START (mbr, entry) = new_start; -+ PC_SLICE_LENGTH (mbr, entry) = new_len; -+ -+ /* Make sure that the MBR has a valid signature. */ -+ PC_MBR_SIG (mbr) = PC_MBR_SIGNATURE; -+ -+ /* Write back the MBR to the disk. */ -+ buf_track = -1; -+ if (! rawwrite (current_drive, 0, mbr)) -+ return 1; -+ -+ return 0; -+} -+ -+static struct builtin builtin_partnew = -+{ -+ "partnew", -+ partnew_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "partnew PART TYPE START LEN", -+ "Create a primary partition at the starting address START with the" -+ " length LEN, with the type TYPE. START and LEN are in sector units." -+}; -+ -+ -+/* parttype PART TYPE */ -+static int -+parttype_func (char *arg, int flags) -+{ -+ int new_type; -+ unsigned long part = 0xFFFFFF; -+ unsigned long start, len, offset, ext_offset; -+ int entry, type; -+ char mbr[512]; -+ -+ /* Get the drive and the partition. */ -+ if (! set_device (arg)) -+ return 1; -+ -+ /* The drive must be a hard disk. */ -+ if (! (current_drive & 0x80)) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ /* The partition must be a PC slice. */ -+ if ((current_partition >> 16) == 0xFF -+ || (current_partition & 0xFFFF) != 0xFFFF) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ /* Get the new partition type. */ -+ arg = skip_to (0, arg); -+ if (! safe_parse_maxint (&arg, &new_type)) -+ return 1; -+ -+ /* The partition type is unsigned char. */ -+ if (new_type > 0xFF) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ /* Look for the partition. */ -+ while (next_partition (current_drive, 0xFFFFFF, &part, &type, -+ &start, &len, &offset, &entry, -+ &ext_offset, mbr)) -+ { -+ if (part == current_partition) -+ { -+ /* Found. */ -+ -+ /* Set the type to NEW_TYPE. */ -+ PC_SLICE_TYPE (mbr, entry) = new_type; -+ -+ /* Write back the MBR to the disk. */ -+ buf_track = -1; -+ if (! rawwrite (current_drive, offset, mbr)) -+ return 1; -+ -+ /* Succeed. */ -+ return 0; -+ } -+ } -+ -+ /* The partition was not found. ERRNUM was set by next_partition. */ -+ return 1; -+} -+ -+static struct builtin builtin_parttype = -+{ -+ "parttype", -+ parttype_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "parttype PART TYPE", -+ "Change the type of the partition PART to TYPE." -+}; -+ -+ -+/* password */ -+static int -+password_func (char *arg, int flags) -+{ -+ int len; -+ password_t type = PASSWORD_PLAIN; -+ -+#ifdef USE_MD5_PASSWORDS -+ if (grub_memcmp (arg, "--md5", 5) == 0) -+ { -+ type = PASSWORD_MD5; -+ arg = skip_to (0, arg); -+ } -+#endif -+ if (grub_memcmp (arg, "--", 2) == 0) -+ { -+ type = PASSWORD_UNSUPPORTED; -+ arg = skip_to (0, arg); -+ } -+ -+ if ((flags & (BUILTIN_CMDLINE | BUILTIN_SCRIPT)) != 0) -+ { -+ /* Do password check! */ -+ char entered[32]; -+ -+ /* Wipe out any previously entered password */ -+ entered[0] = 0; -+ get_cmdline ("Password: ", entered, 31, '*', 0); -+ -+ nul_terminate (arg); -+ if (check_password (entered, arg, type) != 0) -+ { -+ errnum = ERR_PRIVILEGED; -+ return 1; -+ } -+ } -+ else -+ { -+ len = grub_strlen (arg); -+ -+ /* PASSWORD NUL NUL ... */ -+ if (len + 2 > PASSWORD_BUFLEN) -+ { -+ errnum = ERR_WONT_FIT; -+ return 1; -+ } -+ -+ /* Copy the password and clear the rest of the buffer. */ -+ password = (char *) PASSWORD_BUF; -+ grub_memmove (password, arg, len); -+ grub_memset (password + len, 0, PASSWORD_BUFLEN - len); -+ password_type = type; -+ } -+ return 0; -+} -+ -+static struct builtin builtin_password = -+{ -+ "password", -+ password_func, -+ BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_NO_ECHO, -+ "password [--md5] PASSWD [FILE]", -+ "If used in the first section of a menu file, disable all" -+ " interactive editing control (menu entry editor and" -+ " command line). If the password PASSWD is entered, it loads the" -+ " FILE as a new config file and restarts the GRUB Stage 2. If you" -+ " omit the argument FILE, then GRUB just unlocks privileged" -+ " instructions. You can also use it in the script section, in" -+ " which case it will ask for the password, before continueing." -+ " The option --md5 tells GRUB that PASSWD is encrypted with" -+ " md5crypt." -+}; -+ -+ -+/* pause */ -+static int -+pause_func (char *arg, int flags) -+{ -+ printf("%s\n", arg); -+ -+ /* If ESC is returned, then abort this entry. */ -+ if (ASCII_CHAR (getkey ()) == 27) -+ return 1; -+ -+ return 0; -+} -+ -+static struct builtin builtin_pause = -+{ -+ "pause", -+ pause_func, -+ BUILTIN_CMDLINE | BUILTIN_NO_ECHO, -+ "pause [MESSAGE ...]", -+ "Print MESSAGE, then wait until a key is pressed." -+}; -+ -+ -+#ifdef GRUB_UTIL -+/* quit */ -+static int -+quit_func (char *arg, int flags) -+{ -+ stop (); -+ -+ /* Never reach here. */ -+ return 0; -+} -+ -+static struct builtin builtin_quit = -+{ -+ "quit", -+ quit_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "quit", -+ "Exit from the GRUB shell." -+}; -+#endif /* GRUB_UTIL */ -+ -+ -+#ifdef SUPPORT_NETBOOT -+/* rarp */ -+static int -+rarp_func (char *arg, int flags) -+{ -+ if (! rarp ()) -+ { -+ if (errnum == ERR_NONE) -+ errnum = ERR_DEV_VALUES; -+ -+ return 1; -+ } -+ -+ /* Notify the configuration. */ -+ print_network_configuration (); -+ return 0; -+} -+ -+static struct builtin builtin_rarp = -+{ -+ "rarp", -+ rarp_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "rarp", -+ "Initialize a network device via RARP." -+}; -+#endif /* SUPPORT_NETBOOT */ -+ -+ -+static int -+read_func (char *arg, int flags) -+{ -+ int addr; -+ -+ if (! safe_parse_maxint (&arg, &addr)) -+ return 1; -+ -+ grub_printf ("Address 0x%x: Value 0x%x\n", -+ addr, *((unsigned *) RAW_ADDR (addr))); -+ return 0; -+} -+ -+static struct builtin builtin_read = -+{ -+ "read", -+ read_func, -+ BUILTIN_CMDLINE, -+ "read ADDR", -+ "Read a 32-bit value from memory at address ADDR and" -+ " display it in hex format." -+}; -+ -+ -+/* reboot */ -+static int -+reboot_func (char *arg, int flags) -+{ -+ grub_reboot (); -+ -+ /* Never reach here. */ -+ return 1; -+} -+ -+static struct builtin builtin_reboot = -+{ -+ "reboot", -+ reboot_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "reboot", -+ "Reboot your system." -+}; -+ -+ -+/* Print the root device information. */ -+static void -+print_root_device (void) -+{ -+ if (saved_drive == NETWORK_DRIVE) -+ { -+ /* Network drive. */ -+ grub_printf (" (nd):"); -+ } -+ else if (saved_drive & 0x80) -+ { -+ /* Hard disk drive. */ -+ grub_printf (" (hd%d", saved_drive - 0x80); -+ -+ if ((saved_partition & 0xFF0000) != 0xFF0000) -+ grub_printf (",%d", saved_partition >> 16); -+ -+ if ((saved_partition & 0x00FF00) != 0x00FF00) -+ grub_printf (",%c", ((saved_partition >> 8) & 0xFF) + 'a'); -+ -+ grub_printf ("):"); -+ } -+ else -+ { -+ /* Floppy disk drive. */ -+ grub_printf (" (fd%d):", saved_drive); -+ } -+ -+ /* Print the filesystem information. */ -+ current_partition = saved_partition; -+ current_drive = saved_drive; -+ print_fsys_type (); -+} -+ -+static int -+real_root_func (char *arg, int attempt_mount) -+{ -+ int hdbias = 0; -+ char *biasptr; -+ char *next; -+ -+ /* If ARG is empty, just print the current root device. */ -+ if (! *arg) -+ { -+ print_root_device (); -+ return 0; -+ } -+ -+ /* Call set_device to get the drive and the partition in ARG. */ -+ next = set_device (arg); -+ if (! next) -+ return 1; -+ -+ /* Ignore ERR_FSYS_MOUNT. */ -+ if (attempt_mount) -+ { -+ if (! open_device () && errnum != ERR_FSYS_MOUNT) -+ return 1; -+ } -+ else -+ { -+ /* This is necessary, because the location of a partition table -+ must be set appropriately. */ -+ if (open_partition ()) -+ { -+ set_bootdev (0); -+ if (errnum) -+ return 1; -+ } -+ } -+ -+ /* Clear ERRNUM. */ -+ errnum = 0; -+ saved_partition = current_partition; -+ saved_drive = current_drive; -+ -+ if (attempt_mount) -+ { -+ /* BSD and chainloading evil hacks !! */ -+ biasptr = skip_to (0, next); -+ safe_parse_maxint (&biasptr, &hdbias); -+ errnum = 0; -+ bootdev = set_bootdev (hdbias); -+ if (errnum) -+ return 1; -+ -+ /* Print the type of the filesystem. */ -+ print_fsys_type (); -+ } -+ -+ return 0; -+} -+ -+static int -+root_func (char *arg, int flags) -+{ -+ return real_root_func (arg, 1); -+} -+ -+static struct builtin builtin_root = -+{ -+ "root", -+ root_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "root [DEVICE [HDBIAS]]", -+ "Set the current "root device" to the device DEVICE, then" -+ " attempt to mount it to get the partition size (for passing the" -+ " partition descriptor in `ES:ESI', used by some chain-loaded" -+ " bootloaders), the BSD drive-type (for booting BSD kernels using" -+ " their native boot format), and correctly determine " -+ " the PC partition where a BSD sub-partition is located. The" -+ " optional HDBIAS parameter is a number to tell a BSD kernel" -+ " how many BIOS drive numbers are on controllers before the current" -+ " one. For example, if there is an IDE disk and a SCSI disk, and your" -+ " FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS." -+}; -+ -+ -+/* rootnoverify */ -+static int -+rootnoverify_func (char *arg, int flags) -+{ -+ return real_root_func (arg, 0); -+} -+ -+static struct builtin builtin_rootnoverify = -+{ -+ "rootnoverify", -+ rootnoverify_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "rootnoverify [DEVICE [HDBIAS]]", -+ "Similar to `root', but don't attempt to mount the partition. This" -+ " is useful for when an OS is outside of the area of the disk that" -+ " GRUB can read, but setting the correct root device is still" -+ " desired. Note that the items mentioned in `root' which" -+ " derived from attempting the mount will NOT work correctly." -+}; -+ -+ -+/* savedefault */ -+static int -+savedefault_func (char *arg, int flags) -+{ -+#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) -+ unsigned long tmp_drive = saved_drive; -+ unsigned long tmp_partition = saved_partition; -+ char *default_file = (char *) DEFAULT_FILE_BUF; -+ char buf[10]; -+ char sect[SECTOR_SIZE]; -+ int entryno; -+ int sector_count = 0; -+ int saved_sectors[2]; -+ int saved_offsets[2]; -+ int saved_lengths[2]; -+ -+ /* Save sector information about at most two sectors. */ -+ auto void disk_read_savesect_func (int sector, int offset, int length); -+ void disk_read_savesect_func (int sector, int offset, int length) -+ { -+ if (sector_count < 2) -+ { -+ saved_sectors[sector_count] = sector; -+ saved_offsets[sector_count] = offset; -+ saved_lengths[sector_count] = length; -+ } -+ sector_count++; -+ } -+ -+ /* This command is only useful when you boot an entry from the menu -+ interface. */ -+ if (! (flags & BUILTIN_SCRIPT)) -+ { -+ errnum = ERR_UNRECOGNIZED; -+ return 1; -+ } -+ -+ /* Determine a saved entry number. */ -+ if (*arg) -+ { -+ if (grub_memcmp (arg, "fallback", sizeof ("fallback") - 1) == 0) -+ { -+ int i; -+ int index = 0; -+ -+ for (i = 0; i < MAX_FALLBACK_ENTRIES; i++) -+ { -+ if (fallback_entries[i] < 0) -+ break; -+ if (fallback_entries[i] == current_entryno) -+ { -+ index = i + 1; -+ break; -+ } -+ } -+ -+ if (index >= MAX_FALLBACK_ENTRIES || fallback_entries[index] < 0) -+ { -+ /* This is the last. */ -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ entryno = fallback_entries[index]; -+ } -+ else if (! safe_parse_maxint (&arg, &entryno)) -+ return 1; -+ } -+ else -+ entryno = current_entryno; -+ -+ /* Open the default file. */ -+ saved_drive = boot_drive; -+ saved_partition = install_partition; -+ if (grub_open (default_file)) -+ { -+ int len; -+ -+ disk_read_hook = disk_read_savesect_func; -+ len = grub_read (buf, sizeof (buf)); -+ disk_read_hook = 0; -+ grub_close (); -+ -+ if (len != sizeof (buf)) -+ { -+ /* This is too small. Do not modify the file manually, please! */ -+ errnum = ERR_READ; -+ goto fail; -+ } -+ -+ if (sector_count > 2) -+ { -+ /* Is this possible?! Too fragmented! */ -+ errnum = ERR_FSYS_CORRUPT; -+ goto fail; -+ } -+ -+ /* Set up a string to be written. */ -+ grub_memset (buf, '\n', sizeof (buf)); -+ grub_sprintf (buf, "%d", entryno); -+ -+ if (saved_lengths[0] < sizeof (buf)) -+ { -+ /* The file is anchored to another file and the first few bytes -+ are spanned in two sectors. Uggh... */ -+ if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE, -+ sect)) -+ goto fail; -+ grub_memmove (sect + saved_offsets[0], buf, saved_lengths[0]); -+ if (! rawwrite (current_drive, saved_sectors[0], sect)) -+ goto fail; -+ -+ if (! rawread (current_drive, saved_sectors[1], 0, SECTOR_SIZE, -+ sect)) -+ goto fail; -+ grub_memmove (sect + saved_offsets[1], -+ buf + saved_lengths[0], -+ sizeof (buf) - saved_lengths[0]); -+ if (! rawwrite (current_drive, saved_sectors[1], sect)) -+ goto fail; -+ } -+ else -+ { -+ /* This is a simple case. It fits into a single sector. */ -+ if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE, -+ sect)) -+ goto fail; -+ grub_memmove (sect + saved_offsets[0], buf, sizeof (buf)); -+ if (! rawwrite (current_drive, saved_sectors[0], sect)) -+ goto fail; -+ } -+ -+ /* Clear the cache. */ -+ buf_track = -1; -+ } -+ -+ fail: -+ saved_drive = tmp_drive; -+ saved_partition = tmp_partition; -+ return errnum; -+#else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */ -+ errnum = ERR_UNRECOGNIZED; -+ return 1; -+#endif /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */ -+} -+ -+static struct builtin builtin_savedefault = -+{ -+ "savedefault", -+ savedefault_func, -+ BUILTIN_CMDLINE, -+ "savedefault [NUM | `fallback']", -+ "Save the current entry as the default boot entry if no argument is" -+ " specified. If a number is specified, this number is saved. If" -+ " `fallback' is used, next fallback entry is saved." -+}; -+ -+ -+#ifdef SUPPORT_SERIAL -+/* serial */ -+static int -+serial_func (char *arg, int flags) -+{ -+ unsigned short port = serial_hw_get_port (0); -+ unsigned int speed = 9600; -+ int word_len = UART_8BITS_WORD; -+ int parity = UART_NO_PARITY; -+ int stop_bit_len = UART_1_STOP_BIT; -+ -+ /* Process GNU-style long options. -+ FIXME: We should implement a getopt-like function, to avoid -+ duplications. */ -+ while (1) -+ { -+ if (grub_memcmp (arg, "--unit=", sizeof ("--unit=") - 1) == 0) -+ { -+ char *p = arg + sizeof ("--unit=") - 1; -+ int unit; -+ -+ if (! safe_parse_maxint (&p, &unit)) -+ return 1; -+ -+ if (unit < 0 || unit > 3) -+ { -+ errnum = ERR_DEV_VALUES; -+ return 1; -+ } -+ -+ port = serial_hw_get_port (unit); -+ } -+ else if (grub_memcmp (arg, "--speed=", sizeof ("--speed=") - 1) == 0) -+ { -+ char *p = arg + sizeof ("--speed=") - 1; -+ int num; -+ -+ if (! safe_parse_maxint (&p, &num)) -+ return 1; -+ -+ speed = (unsigned int) num; -+ } -+ else if (grub_memcmp (arg, "--port=", sizeof ("--port=") - 1) == 0) -+ { -+ char *p = arg + sizeof ("--port=") - 1; -+ int num; -+ -+ if (! safe_parse_maxint (&p, &num)) -+ return 1; -+ -+ port = (unsigned short) num; -+ } -+ else if (grub_memcmp (arg, "--word=", sizeof ("--word=") - 1) == 0) -+ { -+ char *p = arg + sizeof ("--word=") - 1; -+ int len; -+ -+ if (! safe_parse_maxint (&p, &len)) -+ return 1; -+ -+ switch (len) -+ { -+ case 5: word_len = UART_5BITS_WORD; break; -+ case 6: word_len = UART_6BITS_WORD; break; -+ case 7: word_len = UART_7BITS_WORD; break; -+ case 8: word_len = UART_8BITS_WORD; break; -+ default: -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ } -+ else if (grub_memcmp (arg, "--stop=", sizeof ("--stop=") - 1) == 0) -+ { -+ char *p = arg + sizeof ("--stop=") - 1; -+ int len; -+ -+ if (! safe_parse_maxint (&p, &len)) -+ return 1; -+ -+ switch (len) -+ { -+ case 1: stop_bit_len = UART_1_STOP_BIT; break; -+ case 2: stop_bit_len = UART_2_STOP_BITS; break; -+ default: -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ } -+ else if (grub_memcmp (arg, "--parity=", sizeof ("--parity=") - 1) == 0) -+ { -+ char *p = arg + sizeof ("--parity=") - 1; -+ -+ if (grub_memcmp (p, "no", sizeof ("no") - 1) == 0) -+ parity = UART_NO_PARITY; -+ else if (grub_memcmp (p, "odd", sizeof ("odd") - 1) == 0) -+ parity = UART_ODD_PARITY; -+ else if (grub_memcmp (p, "even", sizeof ("even") - 1) == 0) -+ parity = UART_EVEN_PARITY; -+ else -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ } -+# ifdef GRUB_UTIL -+ /* In the grub shell, don't use any port number but open a tty -+ device instead. */ -+ else if (grub_memcmp (arg, "--device=", sizeof ("--device=") - 1) == 0) -+ { -+ char *p = arg + sizeof ("--device=") - 1; -+ char dev[256]; /* XXX */ -+ char *q = dev; -+ -+ while (*p && ! grub_isspace (*p)) -+ *q++ = *p++; -+ -+ *q = 0; -+ serial_set_device (dev); -+ } -+# endif /* GRUB_UTIL */ -+ else -+ break; -+ -+ arg = skip_to (0, arg); -+ } -+ -+ /* Initialize the serial unit. */ -+ if (! serial_hw_init (port, speed, word_len, parity, stop_bit_len)) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_serial = -+{ -+ "serial", -+ serial_func, -+ BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "serial [--unit=UNIT] [--port=PORT] [--speed=SPEED] [--word=WORD] [--parity=PARITY] [--stop=STOP] [--device=DEV]", -+ "Initialize a serial device. UNIT is a digit that specifies which serial" -+ " device is used (e.g. 0 == COM1). If you need to specify the port number," -+ " set it by --port. SPEED is the DTE-DTE speed. WORD is the word length," -+ " PARITY is the type of parity, which is one of `no', `odd' and `even'." -+ " STOP is the length of stop bit(s). The option --device can be used only" -+ " in the grub shell, which specifies the file name of a tty device. The" -+ " default values are COM1, 9600, 8N1." -+}; -+#endif /* SUPPORT_SERIAL */ -+ -+ -+/* setkey */ -+struct keysym -+{ -+ char *unshifted_name; /* the name in unshifted state */ -+ char *shifted_name; /* the name in shifted state */ -+ unsigned char unshifted_ascii; /* the ascii code in unshifted state */ -+ unsigned char shifted_ascii; /* the ascii code in shifted state */ -+ unsigned char keycode; /* keyboard scancode */ -+}; -+ -+/* The table for key symbols. If the "shifted" member of an entry is -+ NULL, the entry does not have shifted state. */ -+static struct keysym keysym_table[] = -+{ -+ {"escape", 0, 0x1b, 0, 0x01}, -+ {"1", "exclam", '1', '!', 0x02}, -+ {"2", "at", '2', '@', 0x03}, -+ {"3", "numbersign", '3', '#', 0x04}, -+ {"4", "dollar", '4', '$', 0x05}, -+ {"5", "percent", '5', '%', 0x06}, -+ {"6", "caret", '6', '^', 0x07}, -+ {"7", "ampersand", '7', '&', 0x08}, -+ {"8", "asterisk", '8', '*', 0x09}, -+ {"9", "parenleft", '9', '(', 0x0a}, -+ {"0", "parenright", '0', ')', 0x0b}, -+ {"minus", "underscore", '-', '_', 0x0c}, -+ {"equal", "plus", '=', '+', 0x0d}, -+ {"backspace", 0, '\b', 0, 0x0e}, -+ {"tab", 0, '\t', 0, 0x0f}, -+ {"q", "Q", 'q', 'Q', 0x10}, -+ {"w", "W", 'w', 'W', 0x11}, -+ {"e", "E", 'e', 'E', 0x12}, -+ {"r", "R", 'r', 'R', 0x13}, -+ {"t", "T", 't', 'T', 0x14}, -+ {"y", "Y", 'y', 'Y', 0x15}, -+ {"u", "U", 'u', 'U', 0x16}, -+ {"i", "I", 'i', 'I', 0x17}, -+ {"o", "O", 'o', 'O', 0x18}, -+ {"p", "P", 'p', 'P', 0x19}, -+ {"bracketleft", "braceleft", '[', '{', 0x1a}, -+ {"bracketright", "braceright", ']', '}', 0x1b}, -+ {"enter", 0, '\n', 0, 0x1c}, -+ {"control", 0, 0, 0, 0x1d}, -+ {"a", "A", 'a', 'A', 0x1e}, -+ {"s", "S", 's', 'S', 0x1f}, -+ {"d", "D", 'd', 'D', 0x20}, -+ {"f", "F", 'f', 'F', 0x21}, -+ {"g", "G", 'g', 'G', 0x22}, -+ {"h", "H", 'h', 'H', 0x23}, -+ {"j", "J", 'j', 'J', 0x24}, -+ {"k", "K", 'k', 'K', 0x25}, -+ {"l", "L", 'l', 'L', 0x26}, -+ {"semicolon", "colon", ';', ':', 0x27}, -+ {"quote", "doublequote", ''', '"', 0x28}, -+ {"backquote", "tilde", '`', '~', 0x29}, -+ {"shift", 0, 0, 0, 0x2a}, -+ {"backslash", "bar", '\', '|', 0x2b}, -+ {"z", "Z", 'z', 'Z', 0x2c}, -+ {"x", "X", 'x', 'X', 0x2d}, -+ {"c", "C", 'c', 'C', 0x2e}, -+ {"v", "V", 'v', 'V', 0x2f}, -+ {"b", "B", 'b', 'B', 0x30}, -+ {"n", "N", 'n', 'N', 0x31}, -+ {"m", "M", 'm', 'M', 0x32}, -+ {"comma", "less", ',', '<', 0x33}, -+ {"period", "greater", '.', '>', 0x34}, -+ {"slash", "question", '/', '?', 0x35}, -+ {"alt", 0, 0, 0, 0x38}, -+ {"space", 0, ' ', 0, 0x39}, -+ {"capslock", 0, 0, 0, 0x3a}, -+ {"F1", 0, 0, 0, 0x3b}, -+ {"F2", 0, 0, 0, 0x3c}, -+ {"F3", 0, 0, 0, 0x3d}, -+ {"F4", 0, 0, 0, 0x3e}, -+ {"F5", 0, 0, 0, 0x3f}, -+ {"F6", 0, 0, 0, 0x40}, -+ {"F7", 0, 0, 0, 0x41}, -+ {"F8", 0, 0, 0, 0x42}, -+ {"F9", 0, 0, 0, 0x43}, -+ {"F10", 0, 0, 0, 0x44}, -+ /* Caution: do not add NumLock here! we cannot deal with it properly. */ -+ {"delete", 0, 0x7f, 0, 0x53} -+}; -+ -+static int -+setkey_func (char *arg, int flags) -+{ -+ char *to_key, *from_key; -+ int to_code, from_code; -+ int map_in_interrupt = 0; -+ -+ auto int find_key_code (char *key); -+ auto int find_ascii_code (char *key); -+ -+ auto int find_key_code (char *key) -+ { -+ int i; -+ -+ for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++) -+ { -+ if (keysym_table[i].unshifted_name && -+ grub_strcmp (key, keysym_table[i].unshifted_name) == 0) -+ return keysym_table[i].keycode; -+ else if (keysym_table[i].shifted_name && -+ grub_strcmp (key, keysym_table[i].shifted_name) == 0) -+ return keysym_table[i].keycode; -+ } -+ -+ return 0; -+ } -+ -+ auto int find_ascii_code (char *key) -+ { -+ int i; -+ -+ for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++) -+ { -+ if (keysym_table[i].unshifted_name && -+ grub_strcmp (key, keysym_table[i].unshifted_name) == 0) -+ return keysym_table[i].unshifted_ascii; -+ else if (keysym_table[i].shifted_name && -+ grub_strcmp (key, keysym_table[i].shifted_name) == 0) -+ return keysym_table[i].shifted_ascii; -+ } -+ -+ return 0; -+ } -+ -+ to_key = arg; -+ from_key = skip_to (0, to_key); -+ -+ if (! *to_key) -+ { -+ /* If the user specifies no argument, reset the key mappings. */ -+ grub_memset (bios_key_map, 0, KEY_MAP_SIZE * sizeof (unsigned short)); -+ grub_memset (ascii_key_map, 0, KEY_MAP_SIZE * sizeof (unsigned short)); -+ -+ return 0; -+ } -+ else if (! *from_key) -+ { -+ /* The user must specify two arguments or zero argument. */ -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ nul_terminate (to_key); -+ nul_terminate (from_key); -+ -+ to_code = find_ascii_code (to_key); -+ from_code = find_ascii_code (from_key); -+ if (! to_code || ! from_code) -+ { -+ map_in_interrupt = 1; -+ to_code = find_key_code (to_key); -+ from_code = find_key_code (from_key); -+ if (! to_code || ! from_code) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ } -+ -+ if (map_in_interrupt) -+ { -+ int i; -+ -+ /* Find an empty slot. */ -+ for (i = 0; i < KEY_MAP_SIZE; i++) -+ { -+ if ((bios_key_map[i] & 0xff) == from_code) -+ /* Perhaps the user wants to overwrite the map. */ -+ break; -+ -+ if (! bios_key_map[i]) -+ break; -+ } -+ -+ if (i == KEY_MAP_SIZE) -+ { -+ errnum = ERR_WONT_FIT; -+ return 1; -+ } -+ -+ if (to_code == from_code) -+ /* If TO is equal to FROM, delete the entry. */ -+ grub_memmove ((char *) &bios_key_map[i], -+ (char *) &bios_key_map[i + 1], -+ sizeof (unsigned short) * (KEY_MAP_SIZE - i)); -+ else -+ bios_key_map[i] = (to_code << 8) | from_code; -+ -+ /* Ugly but should work. */ -+ unset_int15_handler (); -+ set_int15_handler (); -+ } -+ else -+ { -+ int i; -+ -+ /* Find an empty slot. */ -+ for (i = 0; i < KEY_MAP_SIZE; i++) -+ { -+ if ((ascii_key_map[i] & 0xff) == from_code) -+ /* Perhaps the user wants to overwrite the map. */ -+ break; -+ -+ if (! ascii_key_map[i]) -+ break; -+ } -+ -+ if (i == KEY_MAP_SIZE) -+ { -+ errnum = ERR_WONT_FIT; -+ return 1; -+ } -+ -+ if (to_code == from_code) -+ /* If TO is equal to FROM, delete the entry. */ -+ grub_memmove ((char *) &ascii_key_map[i], -+ (char *) &ascii_key_map[i + 1], -+ sizeof (unsigned short) * (KEY_MAP_SIZE - i)); -+ else -+ ascii_key_map[i] = (to_code << 8) | from_code; -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_setkey = -+{ -+ "setkey", -+ setkey_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "setkey [TO_KEY FROM_KEY]", -+ "Change the keyboard map. The key FROM_KEY is mapped to the key TO_KEY." -+ " A key must be an alphabet, a digit, or one of these: escape, exclam," -+ " at, numbersign, dollar, percent, caret, ampersand, asterisk, parenleft," -+ " parenright, minus, underscore, equal, plus, backspace, tab, bracketleft," -+ " braceleft, bracketright, braceright, enter, control, semicolon, colon," -+ " quote, doublequote, backquote, tilde, shift, backslash, bar, comma," -+ " less, period, greater, slash, question, alt, space, capslock, FX (X" -+ " is a digit), and delete. If no argument is specified, reset key" -+ " mappings." -+}; -+ -+ -+/* setup */ -+static int -+setup_func (char *arg, int flags) -+{ -+ /* Point to the string of the installed drive/partition. */ -+ char *install_ptr; -+ /* Point to the string of the drive/parition where the GRUB images -+ reside. */ -+ char *image_ptr; -+ unsigned long installed_drive, installed_partition; -+ unsigned long image_drive, image_partition; -+ unsigned long tmp_drive, tmp_partition; -+ char stage1[64]; -+ char stage2[64]; -+ char config_filename[64]; -+ char real_config_filename[64]; -+ char cmd_arg[256]; -+ char device[16]; -+ char *buffer = (char *) RAW_ADDR (0x100000); -+ int is_force_lba = 0; -+ char *stage2_arg = 0; -+ char *prefix = 0; -+ -+ auto int check_file (char *file); -+ auto void sprint_device (int drive, int partition); -+ auto int embed_stage1_5 (char * stage1_5, int drive, int partition); -+ -+ /* Check if the file FILE exists like Autoconf. */ -+ int check_file (char *file) -+ { -+ int ret; -+ -+ grub_printf (" Checking if "%s" exists... ", file); -+ ret = grub_open (file); -+ if (ret) -+ { -+ grub_close (); -+ grub_printf ("yes\n"); -+ } -+ else -+ grub_printf ("no\n"); -+ -+ return ret; -+ } -+ -+ /* Construct a device name in DEVICE. */ -+ void sprint_device (int drive, int partition) -+ { -+ grub_sprintf (device, "(%cd%d", -+ (drive & 0x80) ? 'h' : 'f', -+ drive & ~0x80); -+ if ((partition & 0xFF0000) != 0xFF0000) -+ { -+ char tmp[16]; -+ grub_sprintf (tmp, ",%d", (partition >> 16) & 0xFF); -+ grub_strncat (device, tmp, 256); -+ } -+ if ((partition & 0x00FF00) != 0x00FF00) -+ { -+ char tmp[16]; -+ grub_sprintf (tmp, ",%c", 'a' + ((partition >> 8) & 0xFF)); -+ grub_strncat (device, tmp, 256); -+ } -+ grub_strncat (device, ")", 256); -+ } -+ -+ int embed_stage1_5 (char *stage1_5, int drive, int partition) -+ { -+ /* We install GRUB into the MBR, so try to embed the -+ Stage 1.5 in the sectors right after the MBR. */ -+ sprint_device (drive, partition); -+ grub_sprintf (cmd_arg, "%s %s", stage1_5, device); -+ -+ /* Notify what will be run. */ -+ grub_printf (" Running "embed %s"... ", cmd_arg); -+ -+ embed_func (cmd_arg, flags); -+ if (! errnum) -+ { -+ /* Construct the blocklist representation. */ -+ grub_sprintf (buffer, "%s%s", device, embed_info); -+ grub_printf ("succeeded\n"); -+ return 1; -+ } -+ else -+ { -+ grub_printf ("failed (this is not fatal)\n"); -+ return 0; -+ } -+ } -+ -+ struct stage1_5_map { -+ char *fsys; -+ char *name; -+ }; -+ struct stage1_5_map stage1_5_map[] = -+ { -+ {"ext2fs", "/e2fs_stage1_5"}, -+ {"fat", "/fat_stage1_5"}, -+ {"ufs2", "/ufs2_stage1_5"}, -+ {"ffs", "/ffs_stage1_5"}, -+ {"iso9660", "/iso9660_stage1_5"}, -+ {"jfs", "/jfs_stage1_5"}, -+ {"minix", "/minix_stage1_5"}, -+ {"reiserfs", "/reiserfs_stage1_5"}, -+ {"vstafs", "/vstafs_stage1_5"}, -+ {"xfs", "/xfs_stage1_5"} -+ }; -+ -+ tmp_drive = saved_drive; -+ tmp_partition = saved_partition; -+ -+ /* Check if the user specifies --force-lba. */ -+ while (1) -+ { -+ if (grub_memcmp ("--force-lba", arg, sizeof ("--force-lba") - 1) == 0) -+ { -+ is_force_lba = 1; -+ arg = skip_to (0, arg); -+ } -+ else if (grub_memcmp ("--prefix=", arg, sizeof ("--prefix=") - 1) == 0) -+ { -+ prefix = arg + sizeof ("--prefix=") - 1; -+ arg = skip_to (0, arg); -+ nul_terminate (prefix); -+ } -+#ifdef GRUB_UTIL -+ else if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0) -+ { -+ stage2_arg = arg; -+ arg = skip_to (0, arg); -+ nul_terminate (stage2_arg); -+ } -+#endif /* GRUB_UTIL */ -+ else -+ break; -+ } -+ -+ install_ptr = arg; -+ image_ptr = skip_to (0, install_ptr); -+ -+ /* Make sure that INSTALL_PTR is valid. */ -+ set_device (install_ptr); -+ if (errnum) -+ return 1; -+ -+ installed_drive = current_drive; -+ installed_partition = current_partition; -+ -+ /* Mount the drive pointed by IMAGE_PTR. */ -+ if (*image_ptr) -+ { -+ /* If the drive/partition where the images reside is specified, -+ get the drive and the partition. */ -+ set_device (image_ptr); -+ if (errnum) -+ return 1; -+ } -+ else -+ { -+ /* If omitted, use SAVED_PARTITION and SAVED_DRIVE. */ -+ current_drive = saved_drive; -+ current_partition = saved_partition; -+ } -+ -+ image_drive = saved_drive = current_drive; -+ image_partition = saved_partition = current_partition; -+ -+ /* Open it. */ -+ if (! open_device ()) -+ goto fail; -+ -+ /* Check if stage1 exists. If the user doesn't specify the option -+ `--prefix', attempt /boot/grub and /grub. */ -+ /* NOTE: It is dangerous to run this command without `--prefix' in the -+ grub shell, since that affects `--stage2'. */ -+ if (! prefix) -+ { -+ prefix = "/boot/grub"; -+ grub_sprintf (stage1, "%s%s", prefix, "/stage1"); -+ if (! check_file (stage1)) -+ { -+ errnum = ERR_NONE; -+ prefix = "/grub"; -+ grub_sprintf (stage1, "%s%s", prefix, "/stage1"); -+ if (! check_file (stage1)) -+ goto fail; -+ } -+ } -+ else -+ { -+ grub_sprintf (stage1, "%s%s", prefix, "/stage1"); -+ if (! check_file (stage1)) -+ goto fail; -+ } -+ -+ /* The prefix was determined. */ -+ grub_sprintf (stage2, "%s%s", prefix, "/stage2"); -+ grub_sprintf (config_filename, "%s%s", prefix, "/menu.lst"); -+ *real_config_filename = 0; -+ -+ /* Check if stage2 exists. */ -+ if (! check_file (stage2)) -+ goto fail; -+ -+ { -+ char *fsys = fsys_table[fsys_type].name; -+ int i; -+ int size = sizeof (stage1_5_map) / sizeof (stage1_5_map[0]); -+ -+ /* Iterate finding the same filesystem name as FSYS. */ -+ for (i = 0; i < size; i++) -+ if (grub_strcmp (fsys, stage1_5_map[i].fsys) == 0) -+ { -+ /* OK, check if the Stage 1.5 exists. */ -+ char stage1_5[64]; -+ -+ grub_sprintf (stage1_5, "%s%s", prefix, stage1_5_map[i].name); -+ if (check_file (stage1_5)) -+ { -+ if (embed_stage1_5 (stage1_5, -+ installed_drive, installed_partition) -+ || embed_stage1_5 (stage1_5, -+ image_drive, image_partition)) -+ { -+ grub_strcpy (real_config_filename, config_filename); -+ sprint_device (image_drive, image_partition); -+ grub_sprintf (config_filename, "%s%s", device, stage2); -+ grub_strcpy (stage2, buffer); -+ } -+ } -+ errnum = 0; -+ break; -+ } -+ } -+ -+ /* Construct a string that is used by the command "install" as its -+ arguments. */ -+ sprint_device (installed_drive, installed_partition); -+ -+#if 1 -+ /* Don't embed a drive number unnecessarily. */ -+ grub_sprintf (cmd_arg, "%s%s%s%s %s%s %s p %s %s", -+ is_force_lba? "--force-lba " : "", -+ stage2_arg? stage2_arg : "", -+ stage2_arg? " " : "", -+ stage1, -+ (installed_drive != image_drive) ? "d " : "", -+ device, -+ stage2, -+ config_filename, -+ real_config_filename); -+#else /* NOT USED */ -+ /* This code was used, because we belived some BIOSes had a problem -+ that they didn't pass a booting drive correctly. It turned out, -+ however, stage1 could trash a booting drive when checking LBA support, -+ because some BIOSes modified the register %dx in INT 13H, AH=48H. -+ So it becamed unclear whether GRUB should use a pre-defined booting -+ drive or not. If the problem still exists, it would be necessary to -+ switch back to this code. */ -+ grub_sprintf (cmd_arg, "%s%s%s%s d %s %s p %s %s", -+ is_force_lba? "--force-lba " : "", -+ stage2_arg? stage2_arg : "", -+ stage2_arg? " " : "", -+ stage1, -+ device, -+ stage2, -+ config_filename, -+ real_config_filename); -+#endif /* NOT USED */ -+ -+ /* Notify what will be run. */ -+ grub_printf (" Running "install %s"... ", cmd_arg); -+ -+ /* Make sure that SAVED_DRIVE and SAVED_PARTITION are identical -+ with IMAGE_DRIVE and IMAGE_PARTITION, respectively. */ -+ saved_drive = image_drive; -+ saved_partition = image_partition; -+ -+ /* Run the command. */ -+ if (! install_func (cmd_arg, flags)) -+ grub_printf ("succeeded\nDone.\n"); -+ else -+ grub_printf ("failed\n"); -+ -+ fail: -+ saved_drive = tmp_drive; -+ saved_partition = tmp_partition; -+ return errnum; -+} -+ -+static struct builtin builtin_setup = -+{ -+ "setup", -+ setup_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "setup [--prefix=DIR] [--stage2=STAGE2_FILE] [--force-lba] INSTALL_DEVICE [IMAGE_DEVICE]", -+ "Set up the installation of GRUB automatically. This command uses" -+ " the more flexible command "install" in the backend and installs" -+ " GRUB into the device INSTALL_DEVICE. If IMAGE_DEVICE is specified," -+ " then find the GRUB images in the device IMAGE_DEVICE, otherwise" -+ " use the current "root device", which can be set by the command" -+ " "root". If you know that your BIOS should support LBA but GRUB" -+ " doesn't work in LBA mode, specify the option `--force-lba'." -+ " If you install GRUB under the grub shell and you cannot unmount the" -+ " partition where GRUB images reside, specify the option `--stage2'" -+ " to tell GRUB the file name under your OS." -+}; -+ -+ -+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) -+/* terminal */ -+static int -+terminal_func (char *arg, int flags) -+{ -+ /* The index of the default terminal in TERM_TABLE. */ -+ int default_term = -1; -+ struct term_entry *prev_term = current_term; -+ int to = -1; -+ int lines = 0; -+ int no_message = 0; -+ unsigned long term_flags = 0; -+ /* XXX: Assume less than 32 terminals. */ -+ unsigned long term_bitmap = 0; -+ -+ /* Get GNU-style long options. */ -+ while (1) -+ { -+ if (grub_memcmp (arg, "--dumb", sizeof ("--dumb") - 1) == 0) -+ term_flags |= TERM_DUMB; -+ else if (grub_memcmp (arg, "--no-echo", sizeof ("--no-echo") - 1) == 0) -+ /* ``--no-echo'' implies ``--no-edit''. */ -+ term_flags |= (TERM_NO_ECHO | TERM_NO_EDIT); -+ else if (grub_memcmp (arg, "--no-edit", sizeof ("--no-edit") - 1) == 0) -+ term_flags |= TERM_NO_EDIT; -+ else if (grub_memcmp (arg, "--timeout=", sizeof ("--timeout=") - 1) == 0) -+ { -+ char *val = arg + sizeof ("--timeout=") - 1; -+ -+ if (! safe_parse_maxint (&val, &to)) -+ return 1; -+ } -+ else if (grub_memcmp (arg, "--lines=", sizeof ("--lines=") - 1) == 0) -+ { -+ char *val = arg + sizeof ("--lines=") - 1; -+ -+ if (! safe_parse_maxint (&val, &lines)) -+ return 1; -+ -+ /* Probably less than four is meaningless.... */ -+ if (lines < 4) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ } -+ else if (grub_memcmp (arg, "--silent", sizeof ("--silent") - 1) == 0) -+ no_message = 1; -+ else -+ break; -+ -+ arg = skip_to (0, arg); -+ } -+ -+ /* If no argument is specified, show current setting. */ -+ if (! *arg) -+ { -+ grub_printf ("%s%s%s%s\n", -+ current_term->name, -+ current_term->flags & TERM_DUMB ? " (dumb)" : "", -+ current_term->flags & TERM_NO_EDIT ? " (no edit)" : "", -+ current_term->flags & TERM_NO_ECHO ? " (no echo)" : ""); -+ return 0; -+ } -+ -+ while (*arg) -+ { -+ int i; -+ char *next = skip_to (0, arg); -+ -+ nul_terminate (arg); -+ -+ for (i = 0; term_table[i].name; i++) -+ { -+ if (grub_strcmp (arg, term_table[i].name) == 0) -+ { -+ if (term_table[i].flags & TERM_NEED_INIT) -+ { -+ errnum = ERR_DEV_NEED_INIT; -+ return 1; -+ } -+ -+ if (default_term < 0) -+ default_term = i; -+ -+ term_bitmap |= (1 << i); -+ break; -+ } -+ } -+ -+ if (! term_table[i].name) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ arg = next; -+ } -+ -+ /* If multiple terminals are specified, wait until the user pushes any -+ key on one of the terminals. */ -+ if (term_bitmap & ~(1 << default_term)) -+ { -+ int time1, time2 = -1; -+ -+ /* XXX: Disable the pager. */ -+ count_lines = -1; -+ -+ /* Get current time. */ -+ while ((time1 = getrtsecs ()) == 0xFF) -+ ; -+ -+ /* Wait for a key input. */ -+ while (to) -+ { -+ int i; -+ -+ for (i = 0; term_table[i].name; i++) -+ { -+ if (term_bitmap & (1 << i)) -+ { -+ if (term_table[i].checkkey () >= 0) -+ { -+ (void) term_table[i].getkey (); -+ default_term = i; -+ -+ goto end; -+ } -+ } -+ } -+ -+ /* Prompt the user, once per sec. */ -+ if ((time1 = getrtsecs ()) != time2 && time1 != 0xFF) -+ { -+ if (! no_message) -+ { -+ /* Need to set CURRENT_TERM to each of selected -+ terminals. */ -+ for (i = 0; term_table[i].name; i++) -+ if (term_bitmap & (1 << i)) -+ { -+ current_term = term_table + i; -+ grub_printf ("\rPress any key to continue.\n"); -+ } -+ -+ /* Restore CURRENT_TERM. */ -+ current_term = prev_term; -+ } -+ -+ time2 = time1; -+ if (to > 0) -+ to--; -+ } -+ } -+ } -+ -+ end: -+ current_term = term_table + default_term; -+ current_term->flags = term_flags; -+ -+ if (lines) -+ max_lines = lines; -+ else -+ /* 24 would be a good default value. */ -+ max_lines = 24; -+ -+ /* If the interface is currently the command-line, -+ restart it to repaint the screen. */ -+ if (current_term != prev_term && (flags & BUILTIN_CMDLINE)) -+ grub_longjmp (restart_cmdline_env, 0); -+ -+ return 0; -+} -+ -+static struct builtin builtin_terminal = -+{ -+ "terminal", -+ terminal_func, -+ BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]", -+ "Select a terminal. When multiple terminals are specified, wait until" -+ " you push any key to continue. If both console and serial are specified," -+ " the terminal to which you input a key first will be selected. If no" -+ " argument is specified, print current setting. The option --dumb" -+ " specifies that your terminal is dumb, otherwise, vt100-compatibility" -+ " is assumed. If you specify --no-echo, input characters won't be echoed." -+ " If you specify --no-edit, the BASH-like editing feature will be disabled." -+ " If --timeout is present, this command will wait at most for SECS" -+ " seconds. The option --lines specifies the maximum number of lines." -+ " The option --silent is used to suppress messages." -+}; -+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ -+ -+ -+#ifdef SUPPORT_SERIAL -+static int -+terminfo_func (char *arg, int flags) -+{ -+ struct terminfo term; -+ -+ if (*arg) -+ { -+ struct -+ { -+ const char *name; -+ char *var; -+ } -+ options[] = -+ { -+ {"--name=", term.name}, -+ {"--cursor-address=", term.cursor_address}, -+ {"--clear-screen=", term.clear_screen}, -+ {"--enter-standout-mode=", term.enter_standout_mode}, -+ {"--exit-standout-mode=", term.exit_standout_mode} -+ }; -+ -+ grub_memset (&term, 0, sizeof (term)); -+ -+ while (*arg) -+ { -+ int i; -+ char *next = skip_to (0, arg); -+ -+ nul_terminate (arg); -+ -+ for (i = 0; i < sizeof (options) / sizeof (options[0]); i++) -+ { -+ const char *name = options[i].name; -+ int len = grub_strlen (name); -+ -+ if (! grub_memcmp (arg, name, len)) -+ { -+ grub_strcpy (options[i].var, ti_unescape_string (arg + len)); -+ break; -+ } -+ } -+ -+ if (i == sizeof (options) / sizeof (options[0])) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return errnum; -+ } -+ -+ arg = next; -+ } -+ -+ if (term.name[0] == 0 || term.cursor_address[0] == 0) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return errnum; -+ } -+ -+ ti_set_term (&term); -+ } -+ else -+ { -+ /* No option specifies printing out current settings. */ -+ ti_get_term (&term); -+ -+ grub_printf ("name=%s\n", -+ ti_escape_string (term.name)); -+ grub_printf ("cursor_address=%s\n", -+ ti_escape_string (term.cursor_address)); -+ grub_printf ("clear_screen=%s\n", -+ ti_escape_string (term.clear_screen)); -+ grub_printf ("enter_standout_mode=%s\n", -+ ti_escape_string (term.enter_standout_mode)); -+ grub_printf ("exit_standout_mode=%s\n", -+ ti_escape_string (term.exit_standout_mode)); -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_terminfo = -+{ -+ "terminfo", -+ terminfo_func, -+ BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "terminfo [--name=NAME --cursor-address=SEQ [--clear-screen=SEQ]" -+ " [--enter-standout-mode=SEQ] [--exit-standout-mode=SEQ]]", -+ -+ "Define the capabilities of your terminal. Use this command to" -+ " define escape sequences, if it is not vt100-compatible." -+ " You may use \e for ESC and ^X for a control character." -+ " If no option is specified, the current settings are printed." -+}; -+#endif /* SUPPORT_SERIAL */ -+ -+ -+/* testload */ -+static int -+testload_func (char *arg, int flags) -+{ -+ int i; -+ -+ kernel_type = KERNEL_TYPE_NONE; -+ -+ if (! grub_open (arg)) -+ return 1; -+ -+ disk_read_hook = disk_read_print_func; -+ -+ /* Perform filesystem test on the specified file. */ -+ /* Read whole file first. */ -+ grub_printf ("Whole file: "); -+ -+ grub_read ((char *) RAW_ADDR (0x100000), -1); -+ -+ /* Now compare two sections of the file read differently. */ -+ -+ for (i = 0; i < 0x10ac0; i++) -+ { -+ *((unsigned char *) RAW_ADDR (0x200000 + i)) = 0; -+ *((unsigned char *) RAW_ADDR (0x300000 + i)) = 1; -+ } -+ -+ /* First partial read. */ -+ grub_printf ("\nPartial read 1: "); -+ -+ grub_seek (0); -+ grub_read ((char *) RAW_ADDR (0x200000), 0x7); -+ grub_read ((char *) RAW_ADDR (0x200007), 0x100); -+ grub_read ((char *) RAW_ADDR (0x200107), 0x10); -+ grub_read ((char *) RAW_ADDR (0x200117), 0x999); -+ grub_read ((char *) RAW_ADDR (0x200ab0), 0x10); -+ grub_read ((char *) RAW_ADDR (0x200ac0), 0x10000); -+ -+ /* Second partial read. */ -+ grub_printf ("\nPartial read 2: "); -+ -+ grub_seek (0); -+ grub_read ((char *) RAW_ADDR (0x300000), 0x10000); -+ grub_read ((char *) RAW_ADDR (0x310000), 0x10); -+ grub_read ((char *) RAW_ADDR (0x310010), 0x7); -+ grub_read ((char *) RAW_ADDR (0x310017), 0x10); -+ grub_read ((char *) RAW_ADDR (0x310027), 0x999); -+ grub_read ((char *) RAW_ADDR (0x3109c0), 0x100); -+ -+ grub_printf ("\nHeader1 = 0x%x, next = 0x%x, next = 0x%x, next = 0x%x\n", -+ *((int *) RAW_ADDR (0x200000)), -+ *((int *) RAW_ADDR (0x200004)), -+ *((int *) RAW_ADDR (0x200008)), -+ *((int *) RAW_ADDR (0x20000c))); -+ -+ grub_printf ("Header2 = 0x%x, next = 0x%x, next = 0x%x, next = 0x%x\n", -+ *((int *) RAW_ADDR (0x300000)), -+ *((int *) RAW_ADDR (0x300004)), -+ *((int *) RAW_ADDR (0x300008)), -+ *((int *) RAW_ADDR (0x30000c))); -+ -+ for (i = 0; i < 0x10ac0; i++) -+ if (*((unsigned char *) RAW_ADDR (0x200000 + i)) -+ != *((unsigned char *) RAW_ADDR (0x300000 + i))) -+ break; -+ -+ grub_printf ("Max is 0x10ac0: i=0x%x, filepos=0x%x\n", i, filepos); -+ disk_read_hook = 0; -+ grub_close (); -+ return 0; -+} -+ -+static struct builtin builtin_testload = -+{ -+ "testload", -+ testload_func, -+ BUILTIN_CMDLINE, -+ "testload FILE", -+ "Read the entire contents of FILE in several different ways and" -+ " compares them, to test the filesystem code. The output is somewhat" -+ " cryptic, but if no errors are reported and the final `i=X," -+ " filepos=Y' reading has X and Y equal, then it is definitely" -+ " consistent, and very likely works correctly subject to a" -+ " consistent offset error. If this test succeeds, then a good next" -+ " step is to try loading a kernel." -+}; -+ -+ -+/* testvbe MODE */ -+static int -+testvbe_func (char *arg, int flags) -+{ -+ int mode_number; -+ struct vbe_controller controller; -+ struct vbe_mode mode; -+ -+ if (! *arg) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ if (! safe_parse_maxint (&arg, &mode_number)) -+ return 1; -+ -+ /* Preset `VBE2'. */ -+ grub_memmove (controller.signature, "VBE2", 4); -+ -+ /* Detect VBE BIOS. */ -+ if (get_vbe_controller_info (&controller) != 0x004F) -+ { -+ grub_printf (" VBE BIOS is not present.\n"); -+ return 0; -+ } -+ -+ if (controller.version < 0x0200) -+ { -+ grub_printf (" VBE version %d.%d is not supported.\n", -+ (int) (controller.version >> 8), -+ (int) (controller.version & 0xFF)); -+ return 0; -+ } -+ -+ if (get_vbe_mode_info (mode_number, &mode) != 0x004F -+ || (mode.mode_attributes & 0x0091) != 0x0091) -+ { -+ grub_printf (" Mode 0x%x is not supported.\n", mode_number); -+ return 0; -+ } -+ -+ /* Now trip to the graphics mode. */ -+ if (set_vbe_mode (mode_number | (1 << 14)) != 0x004F) -+ { -+ grub_printf (" Switching to Mode 0x%x failed.\n", mode_number); -+ return 0; -+ } -+ -+ /* Draw something on the screen... */ -+ { -+ unsigned char *base_buf = (unsigned char *) mode.phys_base; -+ int scanline = controller.version >= 0x0300 -+ ? mode.linear_bytes_per_scanline : mode.bytes_per_scanline; -+ /* FIXME: this assumes that any depth is a modulo of 8. */ -+ int bpp = mode.bits_per_pixel / 8; -+ int width = mode.x_resolution; -+ int height = mode.y_resolution; -+ int x, y; -+ unsigned color = 0; -+ -+ /* Iterate drawing on the screen, until the user hits any key. */ -+ while (checkkey () == -1) -+ { -+ for (y = 0; y < height; y++) -+ { -+ unsigned char *line_buf = base_buf + scanline * y; -+ -+ for (x = 0; x < width; x++) -+ { -+ unsigned char *buf = line_buf + bpp * x; -+ int i; -+ -+ for (i = 0; i < bpp; i++, buf++) -+ *buf = (color >> (i * 8)) & 0xff; -+ } -+ -+ color++; -+ } -+ } -+ -+ /* Discard the input. */ -+ getkey (); -+ } -+ -+ /* Back to the default text mode. */ -+ if (set_vbe_mode (0x03) != 0x004F) -+ { -+ /* Why?! */ -+ grub_reboot (); -+ } -+ -+ return 0; -+} -+ -+static struct builtin builtin_testvbe = -+{ -+ "testvbe", -+ testvbe_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "testvbe MODE", -+ "Test the VBE mode MODE. Hit any key to return." -+}; -+ -+ -+#ifdef SUPPORT_NETBOOT -+/* tftpserver */ -+static int -+tftpserver_func (char *arg, int flags) -+{ -+ if (! *arg || ! ifconfig (0, 0, 0, arg)) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ -+ print_network_configuration (); -+ return 0; -+} -+ -+static struct builtin builtin_tftpserver = -+{ -+ "tftpserver", -+ tftpserver_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "tftpserver IPADDR", -+ "Override the TFTP server address." -+}; -+#endif /* SUPPORT_NETBOOT */ -+ -+ -+/* timeout */ -+static int -+timeout_func (char *arg, int flags) -+{ -+ if (! safe_parse_maxint (&arg, &grub_timeout)) -+ return 1; -+ -+ return 0; -+} -+ -+static struct builtin builtin_timeout = -+{ -+ "timeout", -+ timeout_func, -+ BUILTIN_MENU, -+#if 0 -+ "timeout SEC", -+ "Set a timeout, in SEC seconds, before automatically booting the" -+ " default entry (normally the first entry defined)." -+#endif -+}; -+ -+ -+/* title */ -+static int -+title_func (char *arg, int flags) -+{ -+ /* This function is not actually used at least currently. */ -+ return 0; -+} -+ -+static struct builtin builtin_title = -+{ -+ "title", -+ title_func, -+ BUILTIN_TITLE, -+#if 0 -+ "title [NAME ...]", -+ "Start a new boot entry, and set its name to the contents of the" -+ " rest of the line, starting with the first non-space character." -+#endif -+}; -+ -+ -+/* unhide */ -+static int -+unhide_func (char *arg, int flags) -+{ -+ if (! set_device (arg)) -+ return 1; -+ -+ if (! set_partition_hidden_flag (0)) -+ return 1; -+ -+ return 0; -+} -+ -+static struct builtin builtin_unhide = -+{ -+ "unhide", -+ unhide_func, -+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, -+ "unhide PARTITION", -+ "Unhide PARTITION by clearing the "hidden" bit in its" -+ " partition type code." -+}; -+ -+ -+/* uppermem */ -+static int -+uppermem_func (char *arg, int flags) -+{ -+ if (! safe_parse_maxint (&arg, (int *) &mbi.mem_upper)) -+ return 1; -+ -+ mbi.flags &= ~MB_INFO_MEM_MAP; -+ return 0; -+} -+ -+static struct builtin builtin_uppermem = -+{ -+ "uppermem", -+ uppermem_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "uppermem KBYTES", -+ "Force GRUB to assume that only KBYTES kilobytes of upper memory are" -+ " installed. Any system address range maps are discarded." -+}; -+ -+ -+/* vbeprobe */ -+static int -+vbeprobe_func (char *arg, int flags) -+{ -+ struct vbe_controller controller; -+ unsigned short *mode_list; -+ int mode_number = -1; -+ -+ auto unsigned long vbe_far_ptr_to_linear (unsigned long); -+ -+ unsigned long vbe_far_ptr_to_linear (unsigned long ptr) -+ { -+ unsigned short seg = (ptr >> 16); -+ unsigned short off = (ptr & 0xFFFF); -+ -+ return (seg << 4) + off; -+ } -+ -+ if (*arg) -+ { -+ if (! safe_parse_maxint (&arg, &mode_number)) -+ return 1; -+ } -+ -+ /* Set the signature to `VBE2', to obtain VBE 3.0 information. */ -+ grub_memmove (controller.signature, "VBE2", 4); -+ -+ if (get_vbe_controller_info (&controller) != 0x004F) -+ { -+ grub_printf (" VBE BIOS is not present.\n"); -+ return 0; -+ } -+ -+ /* Check the version. */ -+ if (controller.version < 0x0200) -+ { -+ grub_printf (" VBE version %d.%d is not supported.\n", -+ (int) (controller.version >> 8), -+ (int) (controller.version & 0xFF)); -+ return 0; -+ } -+ -+ /* Print some information. */ -+ grub_printf (" VBE version %d.%d\n", -+ (int) (controller.version >> 8), -+ (int) (controller.version & 0xFF)); -+ -+ /* Iterate probing modes. */ -+ for (mode_list -+ = (unsigned short *) vbe_far_ptr_to_linear (controller.video_mode); -+ *mode_list != 0xFFFF; -+ mode_list++) -+ { -+ struct vbe_mode mode; -+ -+ if (get_vbe_mode_info (*mode_list, &mode) != 0x004F) -+ continue; -+ -+ /* Skip this, if this is not supported or linear frame buffer -+ mode is not support. */ -+ if ((mode.mode_attributes & 0x0081) != 0x0081) -+ continue; -+ -+ if (mode_number == -1 || mode_number == *mode_list) -+ { -+ char *model; -+ switch (mode.memory_model) -+ { -+ case 0x00: model = "Text"; break; -+ case 0x01: model = "CGA graphics"; break; -+ case 0x02: model = "Hercules graphics"; break; -+ case 0x03: model = "Planar"; break; -+ case 0x04: model = "Packed pixel"; break; -+ case 0x05: model = "Non-chain 4, 256 color"; break; -+ case 0x06: model = "Direct Color"; break; -+ case 0x07: model = "YUV"; break; -+ default: model = "Unknown"; break; -+ } -+ -+ grub_printf (" 0x%x: %s, %ux%ux%u\n", -+ (unsigned) *mode_list, -+ model, -+ (unsigned) mode.x_resolution, -+ (unsigned) mode.y_resolution, -+ (unsigned) mode.bits_per_pixel); -+ -+ if (mode_number != -1) -+ break; -+ } -+ } -+ -+ if (mode_number != -1 && mode_number != *mode_list) -+ grub_printf (" Mode 0x%x is not found or supported.\n", mode_number); -+ -+ return 0; -+} -+ -+static struct builtin builtin_vbeprobe = -+{ -+ "vbeprobe", -+ vbeprobe_func, -+ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, -+ "vbeprobe [MODE]", -+ "Probe VBE information. If the mode number MODE is specified, show only" -+ " the information about only the mode." -+}; -+ -+ -+/* The table of builtin commands. Sorted in dictionary order. */ -+struct builtin *builtin_table[] = -+{ -+ &builtin_blocklist, -+ &builtin_boot, -+#ifdef SUPPORT_NETBOOT -+ &builtin_bootp, -+#endif /* SUPPORT_NETBOOT */ -+ &builtin_cat, -+ &builtin_chainloader, -+ &builtin_cmp, -+ &builtin_color, -+ &builtin_configfile, -+ &builtin_debug, -+ &builtin_default, -+#ifdef GRUB_UTIL -+ &builtin_device, -+#endif /* GRUB_UTIL */ -+#ifdef SUPPORT_NETBOOT -+ &builtin_dhcp, -+#endif /* SUPPORT_NETBOOT */ -+ &builtin_displayapm, -+ &builtin_displaymem, -+#ifdef GRUB_UTIL -+ &builtin_dump, -+#endif /* GRUB_UTIL */ -+ &builtin_embed, -+ &builtin_fallback, -+ &builtin_find, -+ &builtin_fstest, -+ &builtin_geometry, -+ &builtin_halt, -+ &builtin_help, -+ &builtin_hiddenmenu, -+ &builtin_hide, -+#ifdef SUPPORT_NETBOOT -+ &builtin_ifconfig, -+#endif /* SUPPORT_NETBOOT */ -+ &builtin_impsprobe, -+ &builtin_initrd, -+ &builtin_install, -+ &builtin_ioprobe, -+ &builtin_kernel, -+ &builtin_lock, -+ &builtin_makeactive, -+ &builtin_map, -+#ifdef USE_MD5_PASSWORDS -+ &builtin_md5crypt, -+#endif /* USE_MD5_PASSWORDS */ -+ &builtin_module, -+ &builtin_modulenounzip, -+ &builtin_pager, -+ &builtin_partnew, -+ &builtin_parttype, -+ &builtin_password, -+ &builtin_pause, -+#ifdef GRUB_UTIL -+ &builtin_quit, -+#endif /* GRUB_UTIL */ -+#ifdef SUPPORT_NETBOOT -+ &builtin_rarp, -+#endif /* SUPPORT_NETBOOT */ -+ &builtin_read, -+ &builtin_reboot, -+ &builtin_root, -+ &builtin_rootnoverify, -+ &builtin_savedefault, -+#ifdef SUPPORT_SERIAL -+ &builtin_serial, -+#endif /* SUPPORT_SERIAL */ -+ &builtin_setkey, -+ &builtin_setup, -+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) -+ &builtin_terminal, -+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ -+#ifdef SUPPORT_SERIAL -+ &builtin_terminfo, -+#endif /* SUPPORT_SERIAL */ -+ &builtin_testload, -+ &builtin_testvbe, -+#ifdef SUPPORT_NETBOOT -+ &builtin_tftpserver, -+#endif /* SUPPORT_NETBOOT */ -+ &builtin_timeout, -+ &builtin_title, -+ &builtin_unhide, -+ &builtin_uppermem, -+ &builtin_vbeprobe, -+ 0 -+}; -diff -Nur grub-0.97/stage2/char_io.c grub-0.97-patched/stage2/char_io.c ---- grub-0.97/stage2/char_io.c 2005-02-01 21:51:23.000000000 +0100 -+++ grub-0.97-patched/stage2/char_io.c 2012-11-11 17:06:52.556085241 +0100 -@@ -35,6 +35,7 @@ - { - "console", - 0, -+ 24, - console_putchar, - console_checkkey, - console_getkey, -@@ -43,13 +44,16 @@ - console_cls, - console_setcolorstate, - console_setcolor, -- console_setcursor -+ console_setcursor, -+ 0, -+ 0 - }, - #ifdef SUPPORT_SERIAL - { - "serial", - /* A serial device must be initialized. */ - TERM_NEED_INIT, -+ 24, - serial_putchar, - serial_checkkey, - serial_getkey, -@@ -58,6 +62,8 @@ - serial_cls, - serial_setcolorstate, - 0, -+ 0, -+ 0, - 0 - }, - #endif /* SUPPORT_SERIAL */ -@@ -65,6 +71,7 @@ - { - "hercules", - 0, -+ 24, - hercules_putchar, - console_checkkey, - console_getkey, -@@ -73,9 +80,28 @@ - hercules_cls, - hercules_setcolorstate, - hercules_setcolor, -- hercules_setcursor -+ hercules_setcursor, -+ 0, -+ 0 - }, - #endif /* SUPPORT_HERCULES */ -+#ifdef SUPPORT_GRAPHICS -+ { "graphics", -+ TERM_NEED_INIT, /* flags */ -+ 30, /* number of lines */ -+ graphics_putchar, /* putchar */ -+ console_checkkey, /* checkkey */ -+ console_getkey, /* getkey */ -+ graphics_getxy, /* getxy */ -+ graphics_gotoxy, /* gotoxy */ -+ graphics_cls, /* cls */ -+ graphics_setcolorstate, /* setcolorstate */ -+ graphics_setcolor, /* setcolor */ -+ graphics_setcursor, /* nocursor */ -+ graphics_init, /* initialize */ -+ graphics_end /* shutdown */ -+ }, -+#endif /* SUPPORT_GRAPHICS */ - /* This must be the last entry. */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } - }; -@@ -1046,13 +1072,15 @@ - the following grub_printf call will print newlines. */ - count_lines = -1; - -+ grub_printf("\n"); - if (current_term->setcolorstate) - current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); - -- grub_printf ("\n[Hit return to continue]"); -+ grub_printf ("[Hit return to continue]"); - - if (current_term->setcolorstate) - current_term->setcolorstate (COLOR_STATE_NORMAL); -+ - - do - { -@@ -1090,7 +1118,7 @@ - cls (void) - { - /* If the terminal is dumb, there is no way to clean the terminal. */ -- if (current_term->flags & TERM_DUMB) -+ if (current_term->flags & TERM_DUMB) - grub_putchar ('\n'); - else - current_term->cls (); -@@ -1174,37 +1202,62 @@ - } - #endif /* ! STAGE1_5 */ - -+#ifdef GRUB_UTIL -+# ifdef __PIC__ -+# if defined(HAVE_START_SYMBOL) && defined(HAVE_END_SYMBOL) -+ extern char start[]; -+ extern char end[]; -+# elif defined(HAVE_USCORE_START_SYMBOL) && defined (HAVE_USCORE_END_SYMBOL) -+ extern char _start[]; -+ extern char _end[]; -+# endif -+# endif -+#endif - int --memcheck (int addr, int len) -+memcheck (unsigned long addr, unsigned long len) - { - #ifdef GRUB_UTIL -- auto int start_addr (void); -- auto int end_addr (void); -+# ifdef __PIC__ -+# if defined(HAVE_START_SYMBOL) && defined(HAVE_END_SYMBOL) -+ if (start <= addr && end > addr + len) -+ return ! errnum; -+# elif defined(HAVE_USCORE_START_SYMBOL) && defined (HAVE_USCORE_END_SYMBOL) -+ if (_start <= addr && _end > addr + len) -+ return ! errnum; -+# endif -+# else /* __PIC__ */ -+ auto unsigned long start_addr (void); -+ auto unsigned long end_addr (void); - -- auto int start_addr (void) -+ auto unsigned long start_addr (void) - { -- int ret; --# if defined(HAVE_START_SYMBOL) -+ unsigned long ret; -+# if defined(HAVE_START_SYMBOL) - asm volatile ("movl $start, %0" : "=a" (ret)); --# elif defined(HAVE_USCORE_START_SYMBOL) -+# elif defined(HAVE_USCORE_START_SYMBOL) - asm volatile ("movl $_start, %0" : "=a" (ret)); --# endif -+# else -+ erk! /* function would return undefined data in this case - barf */ -+# endif - return ret; - } - -- auto int end_addr (void) -+ auto unsigned long end_addr (void) - { -- int ret; --# if defined(HAVE_END_SYMBOL) -+ unsigned long ret; -+# if defined(HAVE_END_SYMBOL) - asm volatile ("movl $end, %0" : "=a" (ret)); --# elif defined(HAVE_USCORE_END_SYMBOL) -+# elif defined(HAVE_USCORE_END_SYMBOL) - asm volatile ("movl $_end, %0" : "=a" (ret)); --# endif -+# else -+ erk! /* function would return undefined data in this case - barf */ -+# endif - return ret; - } - - if (start_addr () <= addr && end_addr () > addr + len) - return ! errnum; -+# endif /* __PIC__ */ - #endif /* GRUB_UTIL */ - - if ((addr < RAW_ADDR (0x1000)) -@@ -1217,10 +1270,20 @@ - return ! errnum; - } - -+void -+grub_memcpy(void *dest, const void *src, int len) -+{ -+ int i; -+ register char *d = (char*)dest, *s = (char*)src; -+ -+ for (i = 0; i < len; i++) -+ d[i] = s[i]; -+} -+ - void * - grub_memmove (void *to, const void *from, int len) - { -- if (memcheck ((int) to, len)) -+ if (memcheck ((unsigned long) to, len)) - { - /* This assembly code is stolen from - linux-2.2.2/include/asm-i386/string.h. This is not very fast -@@ -1258,7 +1321,7 @@ - { - char *p = start; - -- if (memcheck ((int) start, len)) -+ if (memcheck ((unsigned long) start, len)) - { - while (len -- > 0) - *p ++ = c; -diff -Nur grub-0.97/stage2/char_io.c.orig grub-0.97-patched/stage2/char_io.c.orig ---- grub-0.97/stage2/char_io.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/stage2/char_io.c.orig 2005-02-01 21:51:23.000000000 +0100 -@@ -0,0 +1,1283 @@ -+/* char_io.c - basic console input and output */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 1999,2000,2001,2002,2004 Free Software Foundation, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * 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, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include <shared.h> -+#include <term.h> -+ -+#ifdef SUPPORT_HERCULES -+# include <hercules.h> -+#endif -+ -+#ifdef SUPPORT_SERIAL -+# include <serial.h> -+#endif -+ -+#ifndef STAGE1_5 -+struct term_entry term_table[] = -+ { -+ { -+ "console", -+ 0, -+ console_putchar, -+ console_checkkey, -+ console_getkey, -+ console_getxy, -+ console_gotoxy, -+ console_cls, -+ console_setcolorstate, -+ console_setcolor, -+ console_setcursor -+ }, -+#ifdef SUPPORT_SERIAL -+ { -+ "serial", -+ /* A serial device must be initialized. */ -+ TERM_NEED_INIT, -+ serial_putchar, -+ serial_checkkey, -+ serial_getkey, -+ serial_getxy, -+ serial_gotoxy, -+ serial_cls, -+ serial_setcolorstate, -+ 0, -+ 0 -+ }, -+#endif /* SUPPORT_SERIAL */ -+#ifdef SUPPORT_HERCULES -+ { -+ "hercules", -+ 0, -+ hercules_putchar, -+ console_checkkey, -+ console_getkey, -+ hercules_getxy, -+ hercules_gotoxy, -+ hercules_cls, -+ hercules_setcolorstate, -+ hercules_setcolor, -+ hercules_setcursor -+ }, -+#endif /* SUPPORT_HERCULES */ -+ /* This must be the last entry. */ -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -+ }; -+ -+/* This must be console. */ -+struct term_entry *current_term = term_table; -+ -+int max_lines = 24; -+int count_lines = -1; -+int use_pager = 1; -+#endif -+ -+void -+print_error (void) -+{ -+ if (errnum > ERR_NONE && errnum < MAX_ERR_NUM) -+#ifndef STAGE1_5 -+ /* printf("\7\n %s\n", err_list[errnum]); */ -+ printf ("\nError %u: %s\n", errnum, err_list[errnum]); -+#else /* STAGE1_5 */ -+ printf ("Error %u\n", errnum); -+#endif /* STAGE1_5 */ -+} -+ -+char * -+convert_to_ascii (char *buf, int c,...) -+{ -+ unsigned long num = *((&c) + 1), mult = 10; -+ char *ptr = buf; -+ -+#ifndef STAGE1_5 -+ if (c == 'x' || c == 'X') -+ mult = 16; -+ -+ if ((num & 0x80000000uL) && c == 'd') -+ { -+ num = (~num) + 1; -+ *(ptr++) = '-'; -+ buf++; -+ } -+#endif -+ -+ do -+ { -+ int dig = num % mult; -+ *(ptr++) = ((dig > 9) ? dig + 'a' - 10 : '0' + dig); -+ } -+ while (num /= mult); -+ -+ /* reorder to correct direction!! */ -+ { -+ char *ptr1 = ptr - 1; -+ char *ptr2 = buf; -+ while (ptr1 > ptr2) -+ { -+ int tmp = *ptr1; -+ *ptr1 = *ptr2; -+ *ptr2 = tmp; -+ ptr1--; -+ ptr2++; -+ } -+ } -+ -+ return ptr; -+} -+ -+void -+grub_putstr (const char *str) -+{ -+ while (*str) -+ grub_putchar (*str++); -+} -+ -+void -+grub_printf (const char *format,...) -+{ -+ int *dataptr = (int *) &format; -+ char c, str[16]; -+ -+ dataptr++; -+ -+ while ((c = *(format++)) != 0) -+ { -+ if (c != '%') -+ grub_putchar (c); -+ else -+ switch (c = *(format++)) -+ { -+#ifndef STAGE1_5 -+ case 'd': -+ case 'x': -+ case 'X': -+#endif -+ case 'u': -+ *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0; -+ grub_putstr (str); -+ break; -+ -+#ifndef STAGE1_5 -+ case 'c': -+ grub_putchar ((*(dataptr++)) & 0xff); -+ break; -+ -+ case 's': -+ grub_putstr ((char *) *(dataptr++)); -+ break; -+#endif -+ } -+ } -+} -+ -+#ifndef STAGE1_5 -+int -+grub_sprintf (char *buffer, const char *format, ...) -+{ -+ /* XXX hohmuth -+ ugly hack -- should unify with printf() */ -+ int *dataptr = (int *) &format; -+ char c, *ptr, str[16]; -+ char *bp = buffer; -+ -+ dataptr++; -+ -+ while ((c = *format++) != 0) -+ { -+ if (c != '%') -+ *bp++ = c; /* putchar(c); */ -+ else -+ switch (c = *(format++)) -+ { -+ case 'd': case 'u': case 'x': -+ *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0; -+ -+ ptr = str; -+ -+ while (*ptr) -+ *bp++ = *(ptr++); /* putchar(*(ptr++)); */ -+ break; -+ -+ case 'c': *bp++ = (*(dataptr++))&0xff; -+ /* putchar((*(dataptr++))&0xff); */ -+ break; -+ -+ case 's': -+ ptr = (char *) (*(dataptr++)); -+ -+ while ((c = *ptr++) != 0) -+ *bp++ = c; /* putchar(c); */ -+ break; -+ } -+ } -+ -+ *bp = 0; -+ return bp - buffer; -+} -+ -+ -+void -+init_page (void) -+{ -+ cls (); -+ -+ grub_printf ("\n GNU GRUB version %s (%dK lower / %dK upper memory)\n\n", -+ version_string, mbi.mem_lower, mbi.mem_upper); -+} -+ -+/* The number of the history entries. */ -+static int num_history = 0; -+ -+/* Get the NOth history. If NO is less than zero or greater than or -+ equal to NUM_HISTORY, return NULL. Otherwise return a valid string. */ -+static char * -+get_history (int no) -+{ -+ if (no < 0 || no >= num_history) -+ return 0; -+ -+ return (char *) HISTORY_BUF + MAX_CMDLINE * no; -+} -+ -+/* Add CMDLINE to the history buffer. */ -+static void -+add_history (const char *cmdline, int no) -+{ -+ grub_memmove ((char *) HISTORY_BUF + MAX_CMDLINE * (no + 1), -+ (char *) HISTORY_BUF + MAX_CMDLINE * no, -+ MAX_CMDLINE * (num_history - no)); -+ grub_strcpy ((char *) HISTORY_BUF + MAX_CMDLINE * no, cmdline); -+ if (num_history < HISTORY_SIZE) -+ num_history++; -+} -+ -+static int -+real_get_cmdline (char *prompt, char *cmdline, int maxlen, -+ int echo_char, int readline) -+{ -+ /* This is a rather complicated function. So explain the concept. -+ -+ A command-line consists of ``section''s. A section is a part of the -+ line which may be displayed on the screen, but a section is never -+ displayed with another section simultaneously. -+ -+ Each section is basically 77 or less characters, but the exception -+ is the first section, which is 78 or less characters, because the -+ starting point is special. See below. -+ -+ The first section contains a prompt and a command-line (or the -+ first part of a command-line when it is too long to be fit in the -+ screen). So, in the first section, the number of command-line -+ characters displayed is 78 minus the length of the prompt (or -+ less). If the command-line has more characters, `>' is put at the -+ position 78 (zero-origin), to inform the user of the hidden -+ characters. -+ -+ Other sections always have `<' at the first position, since there -+ is absolutely a section before each section. If there is a section -+ after another section, this section consists of 77 characters and -+ `>' at the last position. The last section has 77 or less -+ characters and doesn't have `>'. -+ -+ Each section other than the last shares some characters with the -+ previous section. This region is called ``margin''. If the cursor -+ is put at the magin which is shared by the first section and the -+ second, the first section is displayed. Otherwise, a displayed -+ section is switched to another section, only if the cursor is put -+ outside that section. */ -+ -+ /* XXX: These should be defined in shared.h, but I leave these here, -+ until this code is freezed. */ -+#define CMDLINE_WIDTH 78 -+#define CMDLINE_MARGIN 10 -+ -+ int xpos, lpos, c, section; -+ /* The length of PROMPT. */ -+ int plen; -+ /* The length of the command-line. */ -+ int llen; -+ /* The index for the history. */ -+ int history = -1; -+ /* The working buffer for the command-line. */ -+ char *buf = (char *) CMDLINE_BUF; -+ /* The kill buffer. */ -+ char *kill_buf = (char *) KILL_BUF; -+ -+ /* Nested function definitions for code simplicity. */ -+ -+ /* The forward declarations of nested functions are prefixed -+ with `auto'. */ -+ auto void cl_refresh (int full, int len); -+ auto void cl_backward (int count); -+ auto void cl_forward (int count); -+ auto void cl_insert (const char *str); -+ auto void cl_delete (int count); -+ auto void cl_init (void); -+ -+ /* Move the cursor backward. */ -+ void cl_backward (int count) -+ { -+ lpos -= count; -+ -+ /* If the cursor is in the first section, display the first section -+ instead of the second. */ -+ if (section == 1 && plen + lpos < CMDLINE_WIDTH) -+ cl_refresh (1, 0); -+ else if (xpos - count < 1) -+ cl_refresh (1, 0); -+ else -+ { -+ xpos -= count; -+ -+ if (current_term->flags & TERM_DUMB) -+ { -+ int i; -+ -+ for (i = 0; i < count; i++) -+ grub_putchar ('\b'); -+ } -+ else -+ gotoxy (xpos, getxy () & 0xFF); -+ } -+ } -+ -+ /* Move the cursor forward. */ -+ void cl_forward (int count) -+ { -+ lpos += count; -+ -+ /* If the cursor goes outside, scroll the screen to the right. */ -+ if (xpos + count >= CMDLINE_WIDTH) -+ cl_refresh (1, 0); -+ else -+ { -+ xpos += count; -+ -+ if (current_term->flags & TERM_DUMB) -+ { -+ int i; -+ -+ for (i = lpos - count; i < lpos; i++) -+ { -+ if (! echo_char) -+ grub_putchar (buf[i]); -+ else -+ grub_putchar (echo_char); -+ } -+ } -+ else -+ gotoxy (xpos, getxy () & 0xFF); -+ } -+ } -+ -+ /* Refresh the screen. If FULL is true, redraw the full line, otherwise, -+ only LEN characters from LPOS. */ -+ void cl_refresh (int full, int len) -+ { -+ int i; -+ int start; -+ int pos = xpos; -+ -+ if (full) -+ { -+ /* Recompute the section number. */ -+ if (lpos + plen < CMDLINE_WIDTH) -+ section = 0; -+ else -+ section = ((lpos + plen - CMDLINE_WIDTH) -+ / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1); -+ -+ /* From the start to the end. */ -+ len = CMDLINE_WIDTH; -+ pos = 0; -+ grub_putchar ('\r'); -+ -+ /* If SECTION is the first section, print the prompt, otherwise, -+ print `<'. */ -+ if (section == 0) -+ { -+ grub_printf ("%s", prompt); -+ len -= plen; -+ pos += plen; -+ } -+ else -+ { -+ grub_putchar ('<'); -+ len--; -+ pos++; -+ } -+ } -+ -+ /* Compute the index to start writing BUF and the resulting position -+ on the screen. */ -+ if (section == 0) -+ { -+ int offset = 0; -+ -+ if (! full) -+ offset = xpos - plen; -+ -+ start = 0; -+ xpos = lpos + plen; -+ start += offset; -+ } -+ else -+ { -+ int offset = 0; -+ -+ if (! full) -+ offset = xpos - 1; -+ -+ start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) -+ + CMDLINE_WIDTH - plen - CMDLINE_MARGIN); -+ xpos = lpos + 1 - start; -+ start += offset; -+ } -+ -+ /* Print BUF. If ECHO_CHAR is not zero, put it instead. */ -+ for (i = start; i < start + len && i < llen; i++) -+ { -+ if (! echo_char) -+ grub_putchar (buf[i]); -+ else -+ grub_putchar (echo_char); -+ -+ pos++; -+ } -+ -+ /* Fill up the rest of the line with spaces. */ -+ for (; i < start + len; i++) -+ { -+ grub_putchar (' '); -+ pos++; -+ } -+ -+ /* If the cursor is at the last position, put `>' or a space, -+ depending on if there are more characters in BUF. */ -+ if (pos == CMDLINE_WIDTH) -+ { -+ if (start + len < llen) -+ grub_putchar ('>'); -+ else -+ grub_putchar (' '); -+ -+ pos++; -+ } -+ -+ /* Back to XPOS. */ -+ if (current_term->flags & TERM_DUMB) -+ { -+ for (i = 0; i < pos - xpos; i++) -+ grub_putchar ('\b'); -+ } -+ else -+ gotoxy (xpos, getxy () & 0xFF); -+ } -+ -+ /* Initialize the command-line. */ -+ void cl_init (void) -+ { -+ /* Distinguish us from other lines and error messages! */ -+ grub_putchar ('\n'); -+ -+ /* Print full line and set position here. */ -+ cl_refresh (1, 0); -+ } -+ -+ /* Insert STR to BUF. */ -+ void cl_insert (const char *str) -+ { -+ int l = grub_strlen (str); -+ -+ if (llen + l < maxlen) -+ { -+ if (lpos == llen) -+ grub_memmove (buf + lpos, str, l + 1); -+ else -+ { -+ grub_memmove (buf + lpos + l, buf + lpos, llen - lpos + 1); -+ grub_memmove (buf + lpos, str, l); -+ } -+ -+ llen += l; -+ lpos += l; -+ if (xpos + l >= CMDLINE_WIDTH) -+ cl_refresh (1, 0); -+ else if (xpos + l + llen - lpos > CMDLINE_WIDTH) -+ cl_refresh (0, CMDLINE_WIDTH - xpos); -+ else -+ cl_refresh (0, l + llen - lpos); -+ } -+ } -+ -+ /* Delete COUNT characters in BUF. */ -+ void cl_delete (int count) -+ { -+ grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1); -+ llen -= count; -+ -+ if (xpos + llen + count - lpos > CMDLINE_WIDTH) -+ cl_refresh (0, CMDLINE_WIDTH - xpos); -+ else -+ cl_refresh (0, llen + count - lpos); -+ } -+ -+ plen = grub_strlen (prompt); -+ llen = grub_strlen (cmdline); -+ -+ if (maxlen > MAX_CMDLINE) -+ { -+ maxlen = MAX_CMDLINE; -+ if (llen >= MAX_CMDLINE) -+ { -+ llen = MAX_CMDLINE - 1; -+ cmdline[MAX_CMDLINE] = 0; -+ } -+ } -+ lpos = llen; -+ grub_strcpy (buf, cmdline); -+ -+ cl_init (); -+ -+ while ((c = ASCII_CHAR (getkey ())) != '\n' && c != '\r') -+ { -+ /* If READLINE is non-zero, handle readline-like key bindings. */ -+ if (readline) -+ { -+ switch (c) -+ { -+ case 9: /* TAB lists completions */ -+ { -+ int i; -+ /* POS points to the first space after a command. */ -+ int pos = 0; -+ int ret; -+ char *completion_buffer = (char *) COMPLETION_BUF; -+ int equal_pos = -1; -+ int is_filename; -+ -+ /* Find the first word. */ -+ while (buf[pos] == ' ') -+ pos++; -+ while (buf[pos] && buf[pos] != '=' && buf[pos] != ' ') -+ pos++; -+ -+ is_filename = (lpos > pos); -+ -+ /* Find the position of the equal character after a -+ command, and replace it with a space. */ -+ for (i = pos; buf[i] && buf[i] != ' '; i++) -+ if (buf[i] == '=') -+ { -+ equal_pos = i; -+ buf[i] = ' '; -+ break; -+ } -+ -+ /* Find the position of the first character in this -+ word. */ -+ for (i = lpos; i > 0 && buf[i - 1] != ' '; i--) -+ ; -+ -+ /* Invalidate the cache, because the user may exchange -+ removable disks. */ -+ buf_drive = -1; -+ -+ /* Copy this word to COMPLETION_BUFFER and do the -+ completion. */ -+ grub_memmove (completion_buffer, buf + i, lpos - i); -+ completion_buffer[lpos - i] = 0; -+ ret = print_completions (is_filename, 1); -+ errnum = ERR_NONE; -+ -+ if (ret >= 0) -+ { -+ /* Found, so insert COMPLETION_BUFFER. */ -+ cl_insert (completion_buffer + lpos - i); -+ -+ if (ret > 0) -+ { -+ /* There are more than one candidates, so print -+ the list. */ -+ grub_putchar ('\n'); -+ print_completions (is_filename, 0); -+ errnum = ERR_NONE; -+ } -+ } -+ -+ /* Restore the command-line. */ -+ if (equal_pos >= 0) -+ buf[equal_pos] = '='; -+ -+ if (ret) -+ cl_init (); -+ } -+ break; -+ case 1: /* C-a go to beginning of line */ -+ cl_backward (lpos); -+ break; -+ case 5: /* C-e go to end of line */ -+ cl_forward (llen - lpos); -+ break; -+ case 6: /* C-f forward one character */ -+ if (lpos < llen) -+ cl_forward (1); -+ break; -+ case 2: /* C-b backward one character */ -+ if (lpos > 0) -+ cl_backward (1); -+ break; -+ case 21: /* C-u kill to beginning of line */ -+ if (lpos == 0) -+ break; -+ /* Copy the string being deleted to KILL_BUF. */ -+ grub_memmove (kill_buf, buf, lpos); -+ kill_buf[lpos] = 0; -+ { -+ /* XXX: Not very clever. */ -+ -+ int count = lpos; -+ -+ cl_backward (lpos); -+ cl_delete (count); -+ } -+ break; -+ case 11: /* C-k kill to end of line */ -+ if (lpos == llen) -+ break; -+ /* Copy the string being deleted to KILL_BUF. */ -+ grub_memmove (kill_buf, buf + lpos, llen - lpos + 1); -+ cl_delete (llen - lpos); -+ break; -+ case 25: /* C-y yank the kill buffer */ -+ cl_insert (kill_buf); -+ break; -+ case 16: /* C-p fetch the previous command */ -+ { -+ char *p; -+ -+ if (history < 0) -+ /* Save the working buffer. */ -+ grub_strcpy (cmdline, buf); -+ else if (grub_strcmp (get_history (history), buf) != 0) -+ /* If BUF is modified, add it into the history list. */ -+ add_history (buf, history); -+ -+ history++; -+ p = get_history (history); -+ if (! p) -+ { -+ history--; -+ break; -+ } -+ -+ grub_strcpy (buf, p); -+ llen = grub_strlen (buf); -+ lpos = llen; -+ cl_refresh (1, 0); -+ } -+ break; -+ case 14: /* C-n fetch the next command */ -+ { -+ char *p; -+ -+ if (history < 0) -+ { -+ break; -+ } -+ else if (grub_strcmp (get_history (history), buf) != 0) -+ /* If BUF is modified, add it into the history list. */ -+ add_history (buf, history); -+ -+ history--; -+ p = get_history (history); -+ if (! p) -+ p = cmdline; -+ -+ grub_strcpy (buf, p); -+ llen = grub_strlen (buf); -+ lpos = llen; -+ cl_refresh (1, 0); -+ } -+ break; -+ } -+ } -+ -+ /* ESC, C-d and C-h are always handled. Actually C-d is not -+ functional if READLINE is zero, as the cursor cannot go -+ backward, but that's ok. */ -+ switch (c) -+ { -+ case 27: /* ESC immediately return 1 */ -+ return 1; -+ case 4: /* C-d delete character under cursor */ -+ if (lpos == llen) -+ break; -+ cl_delete (1); -+ break; -+ case 8: /* C-h backspace */ -+# ifdef GRUB_UTIL -+ case 127: /* also backspace */ -+# endif -+ if (lpos > 0) -+ { -+ cl_backward (1); -+ cl_delete (1); -+ } -+ break; -+ default: /* insert printable character into line */ -+ if (c >= ' ' && c <= '~') -+ { -+ char str[2]; -+ -+ str[0] = c; -+ str[1] = 0; -+ cl_insert (str); -+ } -+ } -+ } -+ -+ grub_putchar ('\n'); -+ -+ /* If ECHO_CHAR is NUL, remove the leading spaces. */ -+ lpos = 0; -+ if (! echo_char) -+ while (buf[lpos] == ' ') -+ lpos++; -+ -+ /* Copy the working buffer to CMDLINE. */ -+ grub_memmove (cmdline, buf + lpos, llen - lpos + 1); -+ -+ /* If the readline-like feature is turned on and CMDLINE is not -+ empty, add it into the history list. */ -+ if (readline && lpos < llen) -+ add_history (cmdline, 0); -+ -+ return 0; -+} -+ -+/* Don't use this with a MAXLEN greater than 1600 or so! The problem -+ is that GET_CMDLINE depends on the everything fitting on the screen -+ at once. So, the whole screen is about 2000 characters, minus the -+ PROMPT, and space for error and status lines, etc. MAXLEN must be -+ at least 1, and PROMPT and CMDLINE must be valid strings (not NULL -+ or zero-length). -+ -+ If ECHO_CHAR is nonzero, echo it instead of the typed character. */ -+int -+get_cmdline (char *prompt, char *cmdline, int maxlen, -+ int echo_char, int readline) -+{ -+ int old_cursor; -+ int ret; -+ -+ old_cursor = setcursor (1); -+ -+ /* Because it is hard to deal with different conditions simultaneously, -+ less functional cases are handled here. Assume that TERM_NO_ECHO -+ implies TERM_NO_EDIT. */ -+ if (current_term->flags & (TERM_NO_ECHO | TERM_NO_EDIT)) -+ { -+ char *p = cmdline; -+ int c; -+ -+ /* Make sure that MAXLEN is not too large. */ -+ if (maxlen > MAX_CMDLINE) -+ maxlen = MAX_CMDLINE; -+ -+ /* Print only the prompt. The contents of CMDLINE is simply discarded, -+ even if it is not empty. */ -+ grub_printf ("%s", prompt); -+ -+ /* Gather characters until a newline is gotten. */ -+ while ((c = ASCII_CHAR (getkey ())) != '\n' && c != '\r') -+ { -+ /* Return immediately if ESC is pressed. */ -+ if (c == 27) -+ { -+ setcursor (old_cursor); -+ return 1; -+ } -+ -+ /* Printable characters are added into CMDLINE. */ -+ if (c >= ' ' && c <= '~') -+ { -+ if (! (current_term->flags & TERM_NO_ECHO)) -+ grub_putchar (c); -+ -+ /* Preceding space characters must be ignored. */ -+ if (c != ' ' || p != cmdline) -+ *p++ = c; -+ } -+ } -+ -+ *p = 0; -+ -+ if (! (current_term->flags & TERM_NO_ECHO)) -+ grub_putchar ('\n'); -+ -+ setcursor (old_cursor); -+ return 0; -+ } -+ -+ /* Complicated features are left to real_get_cmdline. */ -+ ret = real_get_cmdline (prompt, cmdline, maxlen, echo_char, readline); -+ setcursor (old_cursor); -+ return ret; -+} -+ -+int -+safe_parse_maxint (char **str_ptr, int *myint_ptr) -+{ -+ char *ptr = *str_ptr; -+ int myint = 0; -+ int mult = 10, found = 0; -+ -+ /* -+ * Is this a hex number? -+ */ -+ if (*ptr == '0' && tolower (*(ptr + 1)) == 'x') -+ { -+ ptr += 2; -+ mult = 16; -+ } -+ -+ while (1) -+ { -+ /* A bit tricky. This below makes use of the equivalence: -+ (A >= B && A <= C) <=> ((A - B) <= (C - B)) -+ when C > B and A is unsigned. */ -+ unsigned int digit; -+ -+ digit = tolower (*ptr) - '0'; -+ if (digit > 9) -+ { -+ digit -= 'a' - '0'; -+ if (mult == 10 || digit > 5) -+ break; -+ digit += 10; -+ } -+ -+ found = 1; -+ if (myint > ((MAXINT - digit) / mult)) -+ { -+ errnum = ERR_NUMBER_OVERFLOW; -+ return 0; -+ } -+ myint = (myint * mult) + digit; -+ ptr++; -+ } -+ -+ if (!found) -+ { -+ errnum = ERR_NUMBER_PARSING; -+ return 0; -+ } -+ -+ *str_ptr = ptr; -+ *myint_ptr = myint; -+ -+ return 1; -+} -+#endif /* STAGE1_5 */ -+ -+#if !defined(STAGE1_5) || defined(FSYS_FAT) -+int -+grub_tolower (int c) -+{ -+ if (c >= 'A' && c <= 'Z') -+ return (c + ('a' - 'A')); -+ -+ return c; -+} -+#endif /* ! STAGE1_5 || FSYS_FAT */ -+ -+int -+grub_isspace (int c) -+{ -+ switch (c) -+ { -+ case ' ': -+ case '\t': -+ case '\r': -+ case '\n': -+ return 1; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+#if !defined(STAGE1_5) || defined(FSYS_ISO9660) -+int -+grub_memcmp (const char *s1, const char *s2, int n) -+{ -+ while (n) -+ { -+ if (*s1 < *s2) -+ return -1; -+ else if (*s1 > *s2) -+ return 1; -+ s1++; -+ s2++; -+ n--; -+ } -+ -+ return 0; -+} -+#endif /* ! STAGE1_5 || FSYS_ISO9660 */ -+ -+#ifndef STAGE1_5 -+int -+grub_strncat (char *s1, const char *s2, int n) -+{ -+ int i = -1; -+ -+ while (++i < n && s1[i] != 0); -+ -+ while (i < n && (s1[i++] = *(s2++)) != 0); -+ -+ s1[n - 1] = 0; -+ -+ if (i >= n) -+ return 0; -+ -+ s1[i] = 0; -+ -+ return 1; -+} -+#endif /* ! STAGE1_5 */ -+ -+/* XXX: This below is an evil hack. Certainly, we should change the -+ strategy to determine what should be defined and what shouldn't be -+ defined for each image. For example, it would be better to create -+ a static library supporting minimal standard C functions and link -+ each image with the library. Complicated things should be left to -+ computer, definitely. -okuji */ -+#if !defined(STAGE1_5) || defined(FSYS_VSTAFS) -+int -+grub_strcmp (const char *s1, const char *s2) -+{ -+ while (*s1 || *s2) -+ { -+ if (*s1 < *s2) -+ return -1; -+ else if (*s1 > *s2) -+ return 1; -+ s1 ++; -+ s2 ++; -+ } -+ -+ return 0; -+} -+#endif /* ! STAGE1_5 || FSYS_VSTAFS */ -+ -+#ifndef STAGE1_5 -+/* Wait for a keypress and return its code. */ -+int -+getkey (void) -+{ -+ return current_term->getkey (); -+} -+ -+/* Check if a key code is available. */ -+int -+checkkey (void) -+{ -+ return current_term->checkkey (); -+} -+#endif /* ! STAGE1_5 */ -+ -+/* Display an ASCII character. */ -+void -+grub_putchar (int c) -+{ -+ if (c == '\n') -+ grub_putchar ('\r'); -+#ifndef STAGE1_5 -+ else if (c == '\t' && current_term->getxy) -+ { -+ int n; -+ -+ n = 8 - ((current_term->getxy () >> 8) & 3); -+ while (n--) -+ grub_putchar (' '); -+ -+ return; -+ } -+#endif /* ! STAGE1_5 */ -+ -+#ifdef STAGE1_5 -+ -+ /* In Stage 1.5, only the normal console is supported. */ -+ console_putchar (c); -+ -+#else /* ! STAGE1_5 */ -+ -+ if (c == '\n') -+ { -+ /* Internal `more'-like feature. */ -+ if (count_lines >= 0) -+ { -+ count_lines++; -+ if (count_lines >= max_lines - 2) -+ { -+ int tmp; -+ -+ /* It's important to disable the feature temporarily, because -+ the following grub_printf call will print newlines. */ -+ count_lines = -1; -+ -+ if (current_term->setcolorstate) -+ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); -+ -+ grub_printf ("\n[Hit return to continue]"); -+ -+ if (current_term->setcolorstate) -+ current_term->setcolorstate (COLOR_STATE_NORMAL); -+ -+ do -+ { -+ tmp = ASCII_CHAR (getkey ()); -+ } -+ while (tmp != '\n' && tmp != '\r'); -+ grub_printf ("\r \r"); -+ -+ /* Restart to count lines. */ -+ count_lines = 0; -+ return; -+ } -+ } -+ } -+ -+ current_term->putchar (c); -+ -+#endif /* ! STAGE1_5 */ -+} -+ -+#ifndef STAGE1_5 -+void -+gotoxy (int x, int y) -+{ -+ current_term->gotoxy (x, y); -+} -+ -+int -+getxy (void) -+{ -+ return current_term->getxy (); -+} -+ -+void -+cls (void) -+{ -+ /* If the terminal is dumb, there is no way to clean the terminal. */ -+ if (current_term->flags & TERM_DUMB) -+ grub_putchar ('\n'); -+ else -+ current_term->cls (); -+} -+ -+int -+setcursor (int on) -+{ -+ if (current_term->setcursor) -+ return current_term->setcursor (on); -+ -+ return 1; -+} -+#endif /* ! STAGE1_5 */ -+ -+int -+substring (const char *s1, const char *s2) -+{ -+ while (*s1 == *s2) -+ { -+ /* The strings match exactly. */ -+ if (! *(s1++)) -+ return 0; -+ s2 ++; -+ } -+ -+ /* S1 is a substring of S2. */ -+ if (*s1 == 0) -+ return -1; -+ -+ /* S1 isn't a substring. */ -+ return 1; -+} -+ -+#ifndef STAGE1_5 -+/* Terminate the string STR with NUL. */ -+int -+nul_terminate (char *str) -+{ -+ int ch; -+ -+ while (*str && ! grub_isspace (*str)) -+ str++; -+ -+ ch = *str; -+ *str = 0; -+ return ch; -+} -+ -+char * -+grub_strstr (const char *s1, const char *s2) -+{ -+ while (*s1) -+ { -+ const char *ptr, *tmp; -+ -+ ptr = s1; -+ tmp = s2; -+ -+ while (*tmp && *ptr == *tmp) -+ ptr++, tmp++; -+ -+ if (tmp > s2 && ! *tmp) -+ return (char *) s1; -+ -+ s1++; -+ } -+ -+ return 0; -+} -+ -+int -+grub_strlen (const char *str) -+{ -+ int len = 0; -+ -+ while (*str++) -+ len++; -+ -+ return len; -+} -+#endif /* ! STAGE1_5 */ -+ -+int -+memcheck (int addr, int len) -+{ -+#ifdef GRUB_UTIL -+ auto int start_addr (void); -+ auto int end_addr (void); -+ -+ auto int start_addr (void) -+ { -+ int ret; -+# if defined(HAVE_START_SYMBOL) -+ asm volatile ("movl $start, %0" : "=a" (ret)); -+# elif defined(HAVE_USCORE_START_SYMBOL) -+ asm volatile ("movl $_start, %0" : "=a" (ret)); -+# endif -+ return ret; -+ } -+ -+ auto int end_addr (void) -+ { -+ int ret; -+# if defined(HAVE_END_SYMBOL) -+ asm volatile ("movl $end, %0" : "=a" (ret)); -+# elif defined(HAVE_USCORE_END_SYMBOL) -+ asm volatile ("movl $_end, %0" : "=a" (ret)); -+# endif -+ return ret; -+ } -+ -+ if (start_addr () <= addr && end_addr () > addr + len) -+ return ! errnum; -+#endif /* GRUB_UTIL */ -+ -+ if ((addr < RAW_ADDR (0x1000)) -+ || (addr < RAW_ADDR (0x100000) -+ && RAW_ADDR (mbi.mem_lower * 1024) < (addr + len)) -+ || (addr >= RAW_ADDR (0x100000) -+ && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len))) -+ errnum = ERR_WONT_FIT; -+ -+ return ! errnum; -+} -+ -+void * -+grub_memmove (void *to, const void *from, int len) -+{ -+ if (memcheck ((int) to, len)) -+ { -+ /* This assembly code is stolen from -+ linux-2.2.2/include/asm-i386/string.h. This is not very fast -+ but compact. */ -+ int d0, d1, d2; -+ -+ if (to < from) -+ { -+ asm volatile ("cld\n\t" -+ "rep\n\t" -+ "movsb" -+ : "=&c" (d0), "=&S" (d1), "=&D" (d2) -+ : "0" (len),"1" (from),"2" (to) -+ : "memory"); -+ } -+ else -+ { -+ asm volatile ("std\n\t" -+ "rep\n\t" -+ "movsb\n\t" -+ "cld" -+ : "=&c" (d0), "=&S" (d1), "=&D" (d2) -+ : "0" (len), -+ "1" (len - 1 + (const char *) from), -+ "2" (len - 1 + (char *) to) -+ : "memory"); -+ } -+ } -+ -+ return errnum ? NULL : to; -+} -+ -+void * -+grub_memset (void *start, int c, int len) -+{ -+ char *p = start; -+ -+ if (memcheck ((int) start, len)) -+ { -+ while (len -- > 0) -+ *p ++ = c; -+ } -+ -+ return errnum ? NULL : start; -+} -+ -+#ifndef STAGE1_5 -+char * -+grub_strcpy (char *dest, const char *src) -+{ -+ grub_memmove (dest, src, grub_strlen (src) + 1); -+ return dest; -+} -+#endif /* ! STAGE1_5 */ -+ -+#ifndef GRUB_UTIL -+# undef memcpy -+/* GCC emits references to memcpy() for struct copies etc. */ -+void *memcpy (void *dest, const void *src, int n) __attribute__ ((alias ("grub_memmove"))); -+#endif -diff -Nur grub-0.97/stage2/common.c grub-0.97-patched/stage2/common.c ---- grub-0.97/stage2/common.c 2004-03-27 17:25:44.000000000 +0100 -+++ grub-0.97-patched/stage2/common.c 2012-11-11 17:06:52.558085305 +0100 -@@ -142,7 +142,8 @@ - init_bios_info (void) - { - #ifndef STAGE1_5 -- unsigned long cont, memtmp, addr; -+ unsigned long memtmp, addr; -+ volatile unsigned long cont; - int drive; - #endif - -diff -Nur grub-0.97/stage2/disk_io.c grub-0.97-patched/stage2/disk_io.c ---- grub-0.97/stage2/disk_io.c 2004-05-23 18:35:24.000000000 +0200 -+++ grub-0.97-patched/stage2/disk_io.c 2012-11-11 17:07:12.740730013 +0100 -@@ -21,6 +21,7 @@ - - #include <shared.h> - #include <filesys.h> -+#include <gpt.h> - - #ifdef SUPPORT_NETBOOT - # define GRUB 1 -@@ -137,7 +138,7 @@ - } - - int --rawread (int drive, int sector, int byte_offset, int byte_len, char *buf) -+rawread (int drive, unsigned int sector, int byte_offset, int byte_len, char *buf) - { - int slen, sectors_per_vtrack; - int sector_size_bits = log2 (buf_geom.sector_size); -@@ -261,7 +262,7 @@ - */ - if (disk_read_func) - { -- int sector_num = sector; -+ unsigned int sector_num = sector; - int length = buf_geom.sector_size - byte_offset; - if (length > size) - length = size; -@@ -291,7 +292,7 @@ - - - int --devread (int sector, int byte_offset, int byte_len, char *buf) -+devread (unsigned int sector, int byte_offset, int byte_len, char *buf) - { - /* - * Check partition boundaries -@@ -330,7 +331,7 @@ - - #ifndef STAGE1_5 - int --rawwrite (int drive, int sector, char *buf) -+rawwrite (int drive, unsigned int sector, char *buf) - { - if (sector == 0) - { -@@ -363,7 +364,7 @@ - } - - int --devwrite (int sector, int sector_count, char *buf) -+devwrite (unsigned int sector, int sector_count, char *buf) - { - #if defined(GRUB_UTIL) && defined(__linux__) - if (current_partition != 0xFFFFFF -@@ -502,8 +503,8 @@ - set_partition_hidden_flag (int hidden) - { - unsigned long part = 0xFFFFFF; -- unsigned long start, len, offset, ext_offset; -- int entry, type; -+ unsigned long start, len, offset, ext_offset, gpt_offset; -+ int entry, type, gpt_count, gpt_size; - char mbr[512]; - - /* The drive must be a hard disk. */ -@@ -524,8 +525,15 @@ - /* Look for the partition. */ - while (next_partition (current_drive, 0xFFFFFF, &part, &type, - &start, &len, &offset, &entry, -- &ext_offset, mbr)) -+ &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr)) - { -+ /* The partition may not be a GPT partition. */ -+ if (gpt_offset != 0) -+ { -+ errnum = ERR_BAD_ARGUMENT; -+ return 1; -+ } -+ - if (part == current_partition) - { - /* Found. */ -@@ -577,11 +585,14 @@ - unsigned long *partition, int *type, - unsigned long *start, unsigned long *len, - unsigned long *offset, int *entry, -- unsigned long *ext_offset, char *buf) -+ unsigned long *ext_offset, -+ unsigned long *gpt_offset, int *gpt_count, -+ int *gpt_size, char *buf) - { - /* Forward declarations. */ - auto int next_bsd_partition (void); - auto int next_pc_slice (void); -+ auto int next_gpt_slice(void); - - /* Get next BSD partition in current PC slice. */ - int next_bsd_partition (void) -@@ -666,6 +677,40 @@ - return 0; - } - -+ /* If this is a GPT partition table, read it as such. */ -+ if (*entry == -1 && *offset == 0 && PC_SLICE_TYPE (buf, 0) == PC_SLICE_TYPE_GPT) -+ { -+ struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf; -+ -+ /* Read in the GPT Partition table header. */ -+ if (! rawread (drive, 1, 0, SECTOR_SIZE, buf)) -+ return 0; -+ -+ if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000) -+ { -+ /* Let gpt_offset point to the first entry in the GPT -+ partition table. This can also be used by callers of -+ next_partition to determine if a entry comes from a -+ GPT partition table or not. */ -+ *gpt_offset = hdr->partitions; -+ *gpt_count = hdr->maxpart; -+ *gpt_size = hdr->partentry_size; -+ -+ return next_gpt_slice(); -+ } -+ else -+ { -+ /* This is not a valid header for a GPT partition table. -+ Re-read the MBR or the boot sector of the extended -+ partition. */ -+ if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf)) -+ return 0; -+ } -+ } -+ -+ /* Not a GPT partition. */ -+ *gpt_offset = 0; -+ - /* Increase the entry number. */ - (*entry)++; - -@@ -710,6 +755,43 @@ - return 1; - } - -+ /* Get the next GPT slice. */ -+ int next_gpt_slice (void) -+ { -+ struct grub_gpt_partentry *gptentry = (struct grub_gpt_partentry *) buf; -+ /* Make GPT partitions show up as PC slices. */ -+ int pc_slice_no = (*partition & 0xFF0000) >> 16; -+ -+ /* If this is the first time... */ -+ if (pc_slice_no == 0xFF) -+ { -+ pc_slice_no = -1; -+ *entry = -1; -+ } -+ -+ do { -+ (*entry)++; -+ -+ if (*entry >= *gpt_count) -+ { -+ errnum = ERR_NO_PART; -+ return 0; -+ } -+ /* Read in the GPT Partition table entry. */ -+ if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf)) -+ return 0; -+ } while (! (gptentry->type1 && gptentry->type2)); -+ -+ pc_slice_no++; -+ *start = gptentry->start; -+ *len = gptentry->end - gptentry->start + 1; -+ *type = PC_SLICE_TYPE_EXT2FS; -+ *entry = pc_slice_no; -+ *partition = (*entry << 16) | 0xFFFF; -+ -+ return 1; -+ } -+ - /* Start the body of this function. */ - - #ifndef STAGE1_5 -@@ -717,6 +799,9 @@ - return 0; - #endif - -+ if (*partition != 0xFFFFFF && *gpt_offset != 0) -+ return next_gpt_slice (); -+ - /* If previous partition is a BSD partition or a PC slice which - contains BSD partitions... */ - if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff)) -@@ -746,6 +831,8 @@ - #ifndef STAGE1_5 - static unsigned long cur_part_offset; - static unsigned long cur_part_addr; -+static unsigned long cur_part_start; -+static int cur_part_entry; - #endif - - /* Open a partition. */ -@@ -755,6 +842,9 @@ - unsigned long dest_partition = current_partition; - unsigned long part_offset; - unsigned long ext_offset; -+ unsigned long gpt_offset; -+ int gpt_count; -+ int gpt_size; - int entry; - char buf[SECTOR_SIZE]; - int bsd_part, pc_slice; -@@ -766,7 +856,8 @@ - int ret = next_partition (current_drive, dest_partition, - ¤t_partition, ¤t_slice, - &part_start, &part_length, -- &part_offset, &entry, &ext_offset, buf); -+ &part_offset, &entry, &ext_offset, -+ &gpt_offset, &gpt_count, &gpt_size, buf); - bsd_part = (current_partition >> 8) & 0xFF; - pc_slice = current_partition >> 16; - return ret; -@@ -800,7 +891,12 @@ - - /* If this is the whole disk, return here. */ - if (! flags && current_partition == 0xFFFFFF) -- return 1; -+ { -+#ifndef STAGE1_5 -+ cur_part_offset = 0; -+#endif /* ! STAGE1_5 */ -+ return 1; -+ } - - if (flags) - dest_partition = 0xFFFFFF; -@@ -815,6 +911,8 @@ - - cur_part_offset = part_offset; - cur_part_addr = BOOT_PART_TABLE + (entry << 4); -+ cur_part_start = part_start; -+ cur_part_entry = entry; - #endif /* ! STAGE1_5 */ - - /* If this is a valid partition... */ -@@ -1142,6 +1240,7 @@ - src = (char *) SCRATCHADDR + BOOTSEC_PART_OFFSET; - while (dst < (char *) BOOT_PART_TABLE + BOOTSEC_PART_LENGTH) - *dst++ = *src++; -+ PC_SLICE_START (BOOT_PART_TABLE - PC_SLICE_OFFSET, cur_part_entry) = cur_part_start; - - /* Set the active flag of the booted partition. */ - for (i = 0; i < 4; i++) -diff -Nur grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patched/stage2/fsys_ext2fs.c ---- grub-0.97/stage2/fsys_ext2fs.c 2004-08-08 20:19:18.000000000 +0200 -+++ grub-0.97-patched/stage2/fsys_ext2fs.c 2012-11-11 17:07:12.750730331 +0100 -@@ -41,6 +41,7 @@ - typedef unsigned short __u16; - typedef __signed__ int __s32; - typedef unsigned int __u32; -+typedef unsigned long long __u64; - - /* - * Constants relative to the data blocks, from ext2_fs.h -@@ -61,9 +62,9 @@ - __u32 s_free_inodes_count; /* Free inodes count */ - __u32 s_first_data_block; /* First Data Block */ - __u32 s_log_block_size; /* Block size */ -- __s32 s_log_frag_size; /* Fragment size */ -+ __s32 s_obso_log_frag_size; /* Obsoleted Fragment size */ - __u32 s_blocks_per_group; /* # Blocks per group */ -- __u32 s_frags_per_group; /* # Fragments per group */ -+ __u32 s_obso_frags_per_group; /* Obsoleted Fragments per group */ - __u32 s_inodes_per_group; /* # Inodes per group */ - __u32 s_mtime; /* Mount time */ - __u32 s_wtime; /* Write time */ -@@ -72,17 +73,62 @@ - __u16 s_magic; /* Magic signature */ - __u16 s_state; /* File system state */ - __u16 s_errors; /* Behaviour when detecting errors */ -- __u16 s_pad; -+ __u16 s_minor_rev_level; /* minor revision level */ - __u32 s_lastcheck; /* time of last check */ - __u32 s_checkinterval; /* max. time between checks */ - __u32 s_creator_os; /* OS */ - __u32 s_rev_level; /* Revision level */ - __u16 s_def_resuid; /* Default uid for reserved blocks */ - __u16 s_def_resgid; /* Default gid for reserved blocks */ -- __u32 s_reserved[235]; /* Padding to the end of the block */ -+ /* -+ * These fields are for EXT2_DYNAMIC_REV superblocks only. -+ * -+ * Note: the difference between the compatible feature set and -+ * the incompatible feature set is that if there is a bit set -+ * in the incompatible feature set that the kernel doesn't -+ * know about, it should refuse to mount the filesystem. -+ * -+ * e2fsck's requirements are more strict; if it doesn't know -+ * about a feature in either the compatible or incompatible -+ * feature set, it must abort and not try to meddle with -+ * things it doesn't understand... -+ */ -+ __u32 s_first_ino; /* First non-reserved inode */ -+ __u16 s_inode_size; /* size of inode structure */ -+ __u16 s_block_group_nr; /* block group # of this superblock */ -+ __u32 s_feature_compat; /* compatible feature set */ -+ __u32 s_feature_incompat; /* incompatible feature set */ -+ __u32 s_feature_ro_compat; /* readonly-compatible feature set */ -+ __u8 s_uuid[16]; /* 128-bit uuid for volume */ -+ char s_volume_name[16]; /* volume name */ -+ char s_last_mounted[64]; /* directory where last mounted */ -+ __u32 s_algorithm_usage_bitmap; /* For compression */ -+ /* -+ * Performance hints. Directory preallocation should only -+ * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on. -+ */ -+ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ -+ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ -+ __u16 s_reserved_gdt_blocks;/* Per group table for online growth */ -+ /* -+ * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set. -+ */ -+ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ -+ __u32 s_journal_inum; /* inode number of journal file */ -+ __u32 s_journal_dev; /* device number of journal file */ -+ __u32 s_last_orphan; /* start of list of inodes to delete */ -+ __u32 s_hash_seed[4]; /* HTREE hash seed */ -+ __u8 s_def_hash_version; /* Default hash version to use */ -+ __u8 s_jnl_backup_type; /* Default type of journal backup */ -+ __u16 s_desc_size; /* size of group descriptor */ -+ __u32 s_default_mount_opts; -+ __u32 s_first_meta_bg; /* First metablock group */ -+ __u32 s_mkfs_time; /* When the filesystem was created */ -+ __u32 s_jnl_blocks[17]; /* Backup of the journal inode */ -+ __u32 s_reserved[172]; /* Padding to the end of the block */ - }; - --struct ext2_group_desc -+struct ext4_group_desc - { - __u32 bg_block_bitmap; /* Blocks bitmap block */ - __u32 bg_inode_bitmap; /* Inodes bitmap block */ -@@ -90,8 +136,18 @@ - __u16 bg_free_blocks_count; /* Free blocks count */ - __u16 bg_free_inodes_count; /* Free inodes count */ - __u16 bg_used_dirs_count; /* Directories count */ -- __u16 bg_pad; -- __u32 bg_reserved[3]; -+ __u16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ -+ __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */ -+ __u16 bg_itable_unused; /* Unused inodes count */ -+ __u16 bg_checksum; /* crc16(sb_uuid+group+desc) */ -+ __u32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ -+ __u32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ -+ __u32 bg_inode_table_hi; /* Inodes table block MSB */ -+ __u16 bg_free_blocks_count_hi;/* Free blocks count MSB */ -+ __u16 bg_free_inodes_count_hi;/* Free inodes count MSB */ -+ __u16 bg_used_dirs_count_hi; /* Directories count MSB */ -+ __u16 bg_itable_unused_hi; /* Unused inodes count MSB */ -+ __u32 bg_reserved2[3]; - }; - - struct ext2_inode -@@ -129,22 +185,22 @@ - __u32 i_block[EXT2_N_BLOCKS]; /* 40: Pointers to blocks */ - __u32 i_version; /* File version (for NFS) */ - __u32 i_file_acl; /* File ACL */ -- __u32 i_dir_acl; /* Directory ACL */ -- __u32 i_faddr; /* Fragment address */ -+ __u32 i_size_high; -+ __u32 i_obso_faddr; /* Obsoleted fragment address */ - union - { - struct - { -- __u8 l_i_frag; /* Fragment number */ -- __u8 l_i_fsize; /* Fragment size */ -- __u16 i_pad1; -- __u32 l_i_reserved2[2]; -+ __u16 l_i_blocks_high; /* were l_i_reserved1 */ -+ __u16 l_i_file_acl_high; -+ __u16 l_i_uid_high; /* these 2 fields */ -+ __u16 l_i_gid_high; /* were reserved2[0] */ -+ __u32 l_i_reserved2; - } - linux2; - struct - { -- __u8 h_i_frag; /* Fragment number */ -- __u8 h_i_fsize; /* Fragment size */ -+ __u16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ - __u16 h_i_mode_high; - __u16 h_i_uid_high; - __u16 h_i_gid_high; -@@ -153,16 +209,36 @@ - hurd2; - struct - { -- __u8 m_i_frag; /* Fragment number */ -- __u8 m_i_fsize; /* Fragment size */ -- __u16 m_pad1; -+ __u16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ -+ __u16 m_i_file_acl_high; - __u32 m_i_reserved2[2]; - } - masix2; - } - osd2; /* OS dependent 2 */ -+ __u16 i_extra_isize; -+ __u16 i_pad1; -+ __u32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */ -+ __u32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */ -+ __u32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */ -+ __u32 i_crtime; /* File Creation time */ -+ __u32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */ -+ __u32 i_version_hi; /* high 32 bits for 64-bit version */ - }; - -+#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ -+#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 /* grub not supported*/ -+#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 -+#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 -+ -+#define EXT4_HAS_INCOMPAT_FEATURE(sb,mask) \ -+ ( sb->s_feature_incompat & mask ) -+ -+#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */ -+#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */ -+ -+#define EXT4_MIN_DESC_SIZE 32 -+ - /* linux/limits.h */ - #define NAME_MAX 255 /* # chars in a file name */ - -@@ -180,6 +256,57 @@ - char name[EXT2_NAME_LEN]; /* File name */ - }; - -+/* linux/ext4_fs_extents.h */ -+/* This is the extent on-disk structure. -+ * It's used at the bottom of the tree. -+ */ -+struct ext4_extent -+ { -+ __u32 ee_block; /* first logical block extent covers */ -+ __u16 ee_len; /* number of blocks covered by extent */ -+ __u16 ee_start_hi; /* high 16 bits of physical block */ -+ __u32 ee_start_lo; /* low 32 bits of physical block */ -+ }; -+ -+/* -+ * This is index on-disk structure. -+ * It's used at all the levels except the bottom. -+ */ -+struct ext4_extent_idx -+ { -+ __u32 ei_block; /* index covers logical blocks from 'block' */ -+ __u32 ei_leaf_lo; /* pointer to the physical block of the next * -+ * level. leaf or next index could be there */ -+ __u16 ei_leaf_hi; /* high 16 bits of physical block */ -+ __u16 ei_unused; -+ }; -+ -+/* -+ * Each block (leaves and indexes), even inode-stored has header. -+ */ -+struct ext4_extent_header -+ { -+ __u16 eh_magic; /* probably will support different formats */ -+ __u16 eh_entries; /* number of valid entries */ -+ __u16 eh_max; /* capacity of store in entries */ -+ __u16 eh_depth; /* has tree real underlying blocks? */ -+ __u32 eh_generation; /* generation of the tree */ -+ }; -+ -+#define EXT4_EXT_MAGIC (0xf30a) -+#define EXT_FIRST_EXTENT(__hdr__) \ -+ ((struct ext4_extent *) (((char *) (__hdr__)) + \ -+ sizeof(struct ext4_extent_header))) -+#define EXT_FIRST_INDEX(__hdr__) \ -+ ((struct ext4_extent_idx *) (((char *) (__hdr__)) + \ -+ sizeof(struct ext4_extent_header))) -+#define EXT_LAST_EXTENT(__hdr__) \ -+ (EXT_FIRST_EXTENT((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1) -+#define EXT_LAST_INDEX(__hdr__) \ -+ (EXT_FIRST_INDEX((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1) -+ -+ -+ - /* linux/ext2fs.h */ - /* - * EXT2_DIR_PAD defines the directory entries boundaries -@@ -218,13 +345,30 @@ - #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) - #define EXT2_ADDR_PER_BLOCK_BITS(s) (log2(EXT2_ADDR_PER_BLOCK(s))) - -+#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */ -+#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */ -+#define EXT2_GOOD_OLD_INODE_SIZE 128 -+#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ -+ EXT2_GOOD_OLD_INODE_SIZE : \ -+ (s)->s_inode_size) -+#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s)) -+ - /* linux/ext2_fs.h */ - #define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) - /* kind of from ext2/super.c */ - #define EXT2_BLOCK_SIZE(s) (1 << EXT2_BLOCK_SIZE_BITS(s)) - /* linux/ext2fs.h */ -+/* sizeof(struct ext2_group_desc) is changed in ext4 -+ * in kernel code, ext2/3 uses sizeof(struct ext2_group_desc) to calculate -+ * number of desc per block, while ext4 uses superblock->s_desc_size in stead -+ * superblock->s_desc_size is not available in ext2/3 -+ * */ -+#define EXT2_DESC_SIZE(s) \ -+ (EXT4_HAS_INCOMPAT_FEATURE(s,EXT4_FEATURE_INCOMPAT_64BIT)? \ -+ s->s_desc_size : EXT4_MIN_DESC_SIZE) - #define EXT2_DESC_PER_BLOCK(s) \ -- (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) -+ (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s)) -+ - /* linux/stat.h */ - #define S_IFMT 00170000 - #define S_IFLNK 0120000 -@@ -386,6 +530,122 @@ - [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)]; - } - -+/* extent binary search index -+ * find closest index in the current level extent tree -+ * kind of from ext4_ext_binsearch_idx in ext4/extents.c -+ */ -+static struct ext4_extent_idx* -+ext4_ext_binsearch_idx(struct ext4_extent_header* eh, int logical_block) -+{ -+ struct ext4_extent_idx *r, *l, *m; -+ l = EXT_FIRST_INDEX(eh) + 1; -+ r = EXT_LAST_INDEX(eh); -+ while (l <= r) -+ { -+ m = l + (r - l) / 2; -+ if (logical_block < m->ei_block) -+ r = m - 1; -+ else -+ l = m + 1; -+ } -+ return (struct ext4_extent_idx*)(l - 1); -+} -+ -+/* extent binary search -+ * find closest extent in the leaf level -+ * kind of from ext4_ext_binsearch in ext4/extents.c -+ */ -+static struct ext4_extent* -+ext4_ext_binsearch(struct ext4_extent_header* eh, int logical_block) -+{ -+ struct ext4_extent *r, *l, *m; -+ l = EXT_FIRST_EXTENT(eh) + 1; -+ r = EXT_LAST_EXTENT(eh); -+ while (l <= r) -+ { -+ m = l + (r - l) / 2; -+ if (logical_block < m->ee_block) -+ r = m - 1; -+ else -+ l = m + 1; -+ } -+ return (struct ext4_extent*)(l - 1); -+} -+ -+/* Maps extents enabled logical block into physical block via an inode. -+ * EXT4_HUGE_FILE_FL should be checked before calling this. -+ */ -+static int -+ext4fs_block_map (int logical_block) -+{ -+ struct ext4_extent_header *eh; -+ struct ext4_extent *ex, *extent; -+ struct ext4_extent_idx *ei, *index; -+ int depth; -+ int i; -+ -+#ifdef E2DEBUG -+ unsigned char *i; -+ for (i = (unsigned char *) INODE; -+ i < ((unsigned char *) INODE + sizeof (struct ext2_inode)); -+ i++) -+ { -+ printf ("%c", "0123456789abcdef"[*i >> 4]); -+ printf ("%c", "0123456789abcdef"[*i % 16]); -+ if (!((i + 1 - (unsigned char *) INODE) % 16)) -+ { -+ printf ("\n"); -+ } -+ else -+ { -+ printf (" "); -+ } -+ } -+ printf ("logical block %d\n", logical_block); -+#endif /* E2DEBUG */ -+ eh = (struct ext4_extent_header*)INODE->i_block; -+ if (eh->eh_magic != EXT4_EXT_MAGIC) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ while((depth = eh->eh_depth) != 0) -+ { /* extent index */ -+ if (eh->eh_magic != EXT4_EXT_MAGIC) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ ei = ext4_ext_binsearch_idx(eh, logical_block); -+ if (ei->ei_leaf_hi) -+ {/* 64bit physical block number not supported */ -+ errnum = ERR_FILELENGTH; -+ return -1; -+ } -+ if (!ext2_rdfsb(ei->ei_leaf_lo, DATABLOCK1)) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ eh = (struct ext4_extent_header*)DATABLOCK1; -+ } -+ -+ /* depth==0, we come to the leaf */ -+ ex = ext4_ext_binsearch(eh, logical_block); -+ if (ex->ee_start_hi) -+ {/* 64bit physical block number not supported */ -+ errnum = ERR_FILELENGTH; -+ return -1; -+ } -+ if ((ex->ee_block + ex->ee_len) < logical_block) -+ { -+ errnum = ERR_FSYS_CORRUPT; -+ return -1; -+ } -+ return ex->ee_start_lo + logical_block - ex->ee_block; -+ -+} -+ - /* preconditions: all preconds of ext2fs_block_map */ - int - ext2fs_read (char *buf, int len) -@@ -420,6 +680,11 @@ - /* find the (logical) block component of our location */ - logical_block = filepos >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK); - offset = filepos & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1); -+ /* map extents enabled logical block number to physical fs on-dick block number */ -+ if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS) -+ && INODE->i_flags & EXT4_EXTENTS_FL) -+ map = ext4fs_block_map (logical_block); -+ else - map = ext2fs_block_map (logical_block); - #ifdef E2DEBUG - printf ("map=%d\n", map); -@@ -504,7 +769,7 @@ - int desc; /* index within that group */ - int ino_blk; /* fs pointer of the inode's information */ - int str_chk = 0; /* used to hold the results of a string compare */ -- struct ext2_group_desc *gdp; -+ struct ext4_group_desc *ext4_gdp; - struct ext2_inode *raw_inode; /* inode info corresponding to current_ino */ - - char linkbuf[PATH_MAX]; /* buffer for following symbolic links */ -@@ -550,10 +815,17 @@ - { - return 0; - } -- gdp = GROUP_DESC; -- ino_blk = gdp[desc].bg_inode_table + -+ ext4_gdp = (struct ext4_group_desc *)( (__u8*)GROUP_DESC + -+ desc * EXT2_DESC_SIZE(SUPERBLOCK)); -+ if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK, EXT4_FEATURE_INCOMPAT_64BIT) -+ && (! ext4_gdp->bg_inode_table_hi)) -+ {/* 64bit itable not supported */ -+ errnum = ERR_FILELENGTH; -+ return -1; -+ } -+ ino_blk = ext4_gdp->bg_inode_table + - (((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group)) -- >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode))); -+ >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK))); - #ifdef E2DEBUG - printf ("inode table fsblock=%d\n", ino_blk); - #endif /* E2DEBUG */ -@@ -565,13 +837,12 @@ - /* reset indirect blocks! */ - mapblock2 = mapblock1 = -1; - -- raw_inode = INODE + -- ((current_ino - 1) -- & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1)); -+ raw_inode = (struct ext2_inode *)((char *)INODE + -+ ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) * -+ EXT2_INODE_SIZE (SUPERBLOCK)); - #ifdef E2DEBUG - printf ("ipb=%d, sizeof(inode)=%d\n", -- (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)), -- sizeof (struct ext2_inode)); -+ EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK)); - printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode); - printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE); - for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode; -@@ -629,7 +900,10 @@ - } - linkbuf[filemax + len] = '\0'; - -- /* Read the symlink data. */ -+ /* Read the symlink data. -+ * Slow symlink is extents enabled -+ * But since grub_read invokes ext2fs_read, nothing to change here -+ * */ - if (! ext2_is_fast_symlink ()) - { - /* Read the necessary blocks, and reset the file pointer. */ -@@ -640,7 +914,9 @@ - } - else - { -- /* Copy the data directly from the inode. */ -+ /* Copy the data directly from the inode. -+ * Fast symlink is not extents enabled -+ * */ - len = filemax; - memmove (linkbuf, (char *) INODE->i_block, len); - } -@@ -674,6 +950,13 @@ - errnum = ERR_BAD_FILETYPE; - return 0; - } -+ /* if file is too large, just stop and report an error*/ -+ if ( (INODE->i_flags & EXT4_HUGE_FILE_FL) && !(INODE->i_size_high)) -+ { -+ /* file too large, stop reading */ -+ errnum = ERR_FILELENGTH; -+ return 0; -+ } - - filemax = (INODE->i_size); - return 1; -@@ -728,17 +1011,28 @@ - } - - /* else, find the (logical) block component of our location */ -+ /* ext4 logical block number the same as ext2/3 */ - blk = loc >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK); - - /* we know which logical block of the directory entry we are looking - for, now we have to translate that to the physical (fs) block on - the disk */ -+ /* map extents enabled logical block number to physical fs on-dick block number */ -+ if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS) -+ && INODE->i_flags & EXT4_EXTENTS_FL) -+ map = ext4fs_block_map (blk); -+ else - map = ext2fs_block_map (blk); - #ifdef E2DEBUG - printf ("fs block=%d\n", map); - #endif /* E2DEBUG */ - mapblock2 = -1; -- if ((map < 0) || !ext2_rdfsb (map, DATABLOCK2)) -+ if (map < 0) -+ { -+ *rest = ch; -+ return 0; -+ } -+ if (!ext2_rdfsb (map, DATABLOCK2)) - { - errnum = ERR_FSYS_CORRUPT; - *rest = ch; -diff -Nur grub-0.97/stage2/gpt.h grub-0.97-patched/stage2/gpt.h ---- grub-0.97/stage2/gpt.h 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/stage2/gpt.h 2012-11-11 17:07:12.697728638 +0100 -@@ -0,0 +1,68 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2006 Free Software Foundation, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * 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, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#ifndef _GPT_H -+#define _GPT_H -+ -+typedef signed char grub_int8_t; -+typedef signed short grub_int16_t; -+typedef signed int grub_int32_t; -+typedef signed long long int grub_int64_t; -+typedef unsigned char grub_uint8_t; -+typedef unsigned short grub_uint16_t; -+typedef unsigned int grub_uint32_t; -+typedef unsigned long long int grub_uint64_t; -+ -+struct grub_gpt_header -+{ -+ grub_uint64_t magic; -+ grub_uint32_t version; -+ grub_uint32_t headersize; -+ grub_uint32_t crc32; -+ grub_uint32_t unused1; -+ grub_uint64_t primary; -+ grub_uint64_t backup; -+ grub_uint64_t start; -+ grub_uint64_t end; -+ grub_uint8_t guid[16]; -+ grub_uint64_t partitions; -+ grub_uint32_t maxpart; -+ grub_uint32_t partentry_size; -+ grub_uint32_t partentry_crc32; -+} __attribute__ ((packed)); -+ -+struct grub_gpt_partentry -+{ -+ grub_uint64_t type1; -+ grub_uint64_t type2; -+ grub_uint8_t guid[16]; -+ grub_uint64_t start; -+ grub_uint64_t end; -+ grub_uint8_t attrib; -+ char name[72]; -+} __attribute__ ((packed)); -+ -+#define GPT_HEADER_MAGIC 0x5452415020494645UL -+ -+#define GPT_ENTRY_SECTOR(size,entry) \ -+ ((((entry) * (size) + 1) & ~(SECTOR_SIZE - 1)) >> SECTOR_BITS) -+#define GPT_ENTRY_INDEX(size,entry) \ -+ ((((entry) * (size) + 1) & (SECTOR_SIZE - 1)) - 1) -+ -+#endif /* _GPT_H */ -diff -Nur grub-0.97/stage2/graphics.c grub-0.97-patched/stage2/graphics.c ---- grub-0.97/stage2/graphics.c 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/stage2/graphics.c 2012-11-11 17:06:33.320470847 +0100 -@@ -0,0 +1,563 @@ -+/* graphics.c - graphics mode support for GRUB */ -+/* Implemented as a terminal type by Jeremy Katz katzj@redhat.com based -+ * on a patch by Paulo César Pereira de Andrade pcpa@conectiva.com.br -+ */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2001,2002 Red Hat, Inc. -+ * Portions copyright (C) 2000 Conectiva, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * 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, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+ -+ -+#ifdef SUPPORT_GRAPHICS -+ -+#include <term.h> -+#include <shared.h> -+#include <graphics.h> -+ -+int saved_videomode; -+unsigned char *font8x16; -+ -+int graphics_inited = 0; -+static char splashimage[64]; -+ -+#define VSHADOW VSHADOW1 -+unsigned char VSHADOW1[38400]; -+unsigned char VSHADOW2[38400]; -+unsigned char VSHADOW4[38400]; -+unsigned char VSHADOW8[38400]; -+ -+/* constants to define the viewable area */ -+const int x0 = 0; -+const int x1 = 80; -+const int y0 = 0; -+const int y1 = 30; -+ -+/* text buffer has to be kept around so that we can write things as we -+ * scroll and the like */ -+unsigned short text[80 * 30]; -+ -+/* why do these have to be kept here? */ -+int foreground = (63 << 16) | (63 << 8) | (63), background = 0, border = 0; -+ -+/* current position */ -+static int fontx = 0; -+static int fonty = 0; -+ -+/* global state so that we don't try to recursively scroll or cursor */ -+static int no_scroll = 0; -+ -+/* color state */ -+static int graphics_standard_color = A_NORMAL; -+static int graphics_normal_color = A_NORMAL; -+static int graphics_highlight_color = A_REVERSE; -+static int graphics_current_color = A_NORMAL; -+static color_state graphics_color_state = COLOR_STATE_STANDARD; -+ -+ -+/* graphics local functions */ -+static void graphics_setxy(int col, int row); -+static void graphics_scroll(); -+ -+/* FIXME: where do these really belong? */ -+static inline void outb(unsigned short port, unsigned char val) -+{ -+ __asm __volatile ("outb %0,%1"::"a" (val), "d" (port)); -+} -+ -+static void MapMask(int value) { -+ outb(0x3c4, 2); -+ outb(0x3c5, value); -+} -+ -+/* bit mask register */ -+static void BitMask(int value) { -+ outb(0x3ce, 8); -+ outb(0x3cf, value); -+} -+ -+ -+ -+/* Set the splash image */ -+void graphics_set_splash(char *splashfile) { -+ grub_strcpy(splashimage, splashfile); -+} -+ -+/* Get the current splash image */ -+char *graphics_get_splash(void) { -+ return splashimage; -+} -+ -+/* Initialize a vga16 graphics display with the palette based off of -+ * the image in splashimage. If the image doesn't exist, leave graphics -+ * mode. */ -+int graphics_init() -+{ -+ if(!grub_file_exists(splashimage)) { -+ return 0; -+ } -+ -+ if (!graphics_inited) { -+ saved_videomode = set_videomode(0x12); -+ } -+ -+ if (!read_image(splashimage)) { -+ set_videomode(saved_videomode); -+ grub_printf("failed to read image\n"); -+ return 0; -+ } -+ -+ font8x16 = (unsigned char*)graphics_get_font(); -+ -+ graphics_inited = 1; -+ -+ /* make sure that the highlight color is set correctly */ -+ graphics_highlight_color = ((graphics_normal_color >> 4) | -+ ((graphics_normal_color & 0xf) << 4)); -+ -+ return 1; -+} -+ -+/* Leave graphics mode */ -+void graphics_end(void) -+{ -+ if (graphics_inited) { -+ set_videomode(saved_videomode); -+ graphics_inited = 0; -+ } -+} -+ -+/* Print ch on the screen. Handle any needed scrolling or the like */ -+void graphics_putchar(int ch) { -+ ch &= 0xff; -+ -+ graphics_cursor(0); -+ -+ if (ch == '\n') { -+ if (fonty + 1 < y1) -+ graphics_setxy(fontx, fonty + 1); -+ else -+ graphics_scroll(); -+ graphics_cursor(1); -+ return; -+ } else if (ch == '\r') { -+ graphics_setxy(x0, fonty); -+ graphics_cursor(1); -+ return; -+ } -+ -+ graphics_cursor(0); -+ -+ text[fonty * 80 + fontx] = ch; -+ text[fonty * 80 + fontx] &= 0x00ff; -+ if (graphics_current_color & 0xf0) -+ text[fonty * 80 + fontx] |= 0x100; -+ -+ graphics_cursor(0); -+ -+ if ((fontx + 1) >= x1) { -+ graphics_setxy(x0, fonty); -+ if (fonty + 1 < y1) -+ graphics_setxy(x0, fonty + 1); -+ else -+ graphics_scroll(); -+ } else { -+ graphics_setxy(fontx + 1, fonty); -+ } -+ -+ graphics_cursor(1); -+} -+ -+/* get the current location of the cursor */ -+int graphics_getxy(void) { -+ return (fontx << 8) | fonty; -+} -+ -+void graphics_gotoxy(int x, int y) { -+ graphics_cursor(0); -+ -+ graphics_setxy(x, y); -+ -+ graphics_cursor(1); -+} -+ -+void graphics_cls(void) { -+ int i; -+ unsigned char *mem, *s1, *s2, *s4, *s8; -+ -+ graphics_cursor(0); -+ graphics_gotoxy(x0, y0); -+ -+ mem = (unsigned char*)VIDEOMEM; -+ s1 = (unsigned char*)VSHADOW1; -+ s2 = (unsigned char*)VSHADOW2; -+ s4 = (unsigned char*)VSHADOW4; -+ s8 = (unsigned char*)VSHADOW8; -+ -+ for (i = 0; i < 80 * 30; i++) -+ text[i] = ' '; -+ graphics_cursor(1); -+ -+ BitMask(0xff); -+ -+ /* plano 1 */ -+ MapMask(1); -+ grub_memcpy(mem, s1, 38400); -+ -+ /* plano 2 */ -+ MapMask(2); -+ grub_memcpy(mem, s2, 38400); -+ -+ /* plano 3 */ -+ MapMask(4); -+ grub_memcpy(mem, s4, 38400); -+ -+ /* plano 4 */ -+ MapMask(8); -+ grub_memcpy(mem, s8, 38400); -+ -+ MapMask(15); -+ -+} -+ -+void graphics_setcolorstate (color_state state) { -+ switch (state) { -+ case COLOR_STATE_STANDARD: -+ graphics_current_color = graphics_standard_color; -+ break; -+ case COLOR_STATE_NORMAL: -+ graphics_current_color = graphics_normal_color; -+ break; -+ case COLOR_STATE_HIGHLIGHT: -+ graphics_current_color = graphics_highlight_color; -+ break; -+ default: -+ graphics_current_color = graphics_standard_color; -+ break; -+ } -+ -+ graphics_color_state = state; -+} -+ -+void graphics_setcolor (int normal_color, int highlight_color) { -+ graphics_normal_color = normal_color; -+ graphics_highlight_color = highlight_color; -+ -+ graphics_setcolorstate (graphics_color_state); -+} -+ -+void graphics_setcursor (int on) { -+ /* FIXME: we don't have a cursor in graphics */ -+ return; -+} -+ -+/* Read in the splashscreen image and set the palette up appropriately. -+ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and -+ * 640x480. */ -+int read_image(char *s) -+{ -+ char buf[32], pal[16]; -+ unsigned char c, base, mask, *s1, *s2, *s4, *s8; -+ unsigned i, len, idx, colors, x, y, width, height; -+ -+ if (!grub_open(s)) -+ return 0; -+ -+ /* read header */ -+ if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) { -+ grub_close(); -+ return 0; -+ } -+ -+ /* parse info */ -+ while (grub_read(&c, 1)) { -+ if (c == '"') -+ break; -+ } -+ -+ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) -+ ; -+ -+ i = 0; -+ width = c - '0'; -+ while (grub_read(&c, 1)) { -+ if (c >= '0' && c <= '9') -+ width = width * 10 + c - '0'; -+ else -+ break; -+ } -+ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) -+ ; -+ -+ height = c - '0'; -+ while (grub_read(&c, 1)) { -+ if (c >= '0' && c <= '9') -+ height = height * 10 + c - '0'; -+ else -+ break; -+ } -+ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) -+ ; -+ -+ colors = c - '0'; -+ while (grub_read(&c, 1)) { -+ if (c >= '0' && c <= '9') -+ colors = colors * 10 + c - '0'; -+ else -+ break; -+ } -+ -+ base = 0; -+ while (grub_read(&c, 1) && c != '"') -+ ; -+ -+ /* palette */ -+ for (i = 0, idx = 1; i < colors; i++) { -+ len = 0; -+ -+ while (grub_read(&c, 1) && c != '"') -+ ; -+ grub_read(&c, 1); /* char */ -+ base = c; -+ grub_read(buf, 4); /* \t c # */ -+ -+ while (grub_read(&c, 1) && c != '"') { -+ if (len < sizeof(buf)) -+ buf[len++] = c; -+ } -+ -+ if (len == 6 && idx < 15) { -+ int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2; -+ int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2; -+ int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2; -+ -+ pal[idx] = base; -+ graphics_set_palette(idx, r, g, b); -+ ++idx; -+ } -+ } -+ -+ x = y = len = 0; -+ -+ s1 = (unsigned char*)VSHADOW1; -+ s2 = (unsigned char*)VSHADOW2; -+ s4 = (unsigned char*)VSHADOW4; -+ s8 = (unsigned char*)VSHADOW8; -+ -+ for (i = 0; i < 38400; i++) -+ s1[i] = s2[i] = s4[i] = s8[i] = 0; -+ -+ /* parse xpm data */ -+ while (y < height) { -+ while (1) { -+ if (!grub_read(&c, 1)) { -+ grub_close(); -+ return 0; -+ } -+ if (c == '"') -+ break; -+ } -+ -+ while (grub_read(&c, 1) && c != '"') { -+ for (i = 1; i < 15; i++) -+ if (pal[i] == c) { -+ c = i; -+ break; -+ } -+ -+ mask = 0x80 >> (x & 7); -+ if (c & 1) -+ s1[len + (x >> 3)] |= mask; -+ if (c & 2) -+ s2[len + (x >> 3)] |= mask; -+ if (c & 4) -+ s4[len + (x >> 3)] |= mask; -+ if (c & 8) -+ s8[len + (x >> 3)] |= mask; -+ -+ if (++x >= 640) { -+ x = 0; -+ -+ if (y < 480) -+ len += 80; -+ ++y; -+ } -+ } -+ } -+ -+ grub_close(); -+ -+ graphics_set_palette(0, (background >> 16), (background >> 8) & 63, -+ background & 63); -+ graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, -+ foreground & 63); -+ graphics_set_palette(0x11, (border >> 16), (border >> 8) & 63, -+ border & 63); -+ -+ return 1; -+} -+ -+ -+/* Convert a character which is a hex digit to the appropriate integer */ -+int hex(int v) -+{ -+ if (v >= 'A' && v <= 'F') -+ return (v - 'A' + 10); -+ if (v >= 'a' && v <= 'f') -+ return (v - 'a' + 10); -+ return (v - '0'); -+} -+ -+ -+/* move the graphics cursor location to col, row */ -+static void graphics_setxy(int col, int row) { -+ if (col >= x0 && col < x1) { -+ fontx = col; -+ cursorX = col << 3; -+ } -+ if (row >= y0 && row < y1) { -+ fonty = row; -+ cursorY = row << 4; -+ } -+} -+ -+/* scroll the screen */ -+static void graphics_scroll() { -+ int i, j; -+ -+ /* we don't want to scroll recursively... that would be bad */ -+ if (no_scroll) -+ return; -+ no_scroll = 1; -+ -+ /* move everything up a line */ -+ for (j = y0 + 1; j < y1; j++) { -+ graphics_gotoxy(x0, j - 1); -+ for (i = x0; i < x1; i++) { -+ graphics_putchar(text[j * 80 + i]); -+ } -+ } -+ -+ /* last line should be blank */ -+ graphics_gotoxy(x0, y1 - 1); -+ for (i = x0; i < x1; i++) -+ graphics_putchar(' '); -+ graphics_setxy(x0, y1 - 1); -+ -+ no_scroll = 0; -+} -+ -+ -+void graphics_cursor(int set) { -+ unsigned char *pat, *mem, *ptr, chr[16 << 2]; -+ int i, ch, invert, offset; -+ -+ if (set && no_scroll) -+ return; -+ -+ offset = cursorY * 80 + fontx; -+ ch = text[fonty * 80 + fontx] & 0xff; -+ invert = (text[fonty * 80 + fontx] & 0xff00) != 0; -+ pat = font8x16 + (ch << 4); -+ -+ mem = (unsigned char*)VIDEOMEM + offset; -+ -+ if (!set) { -+ for (i = 0; i < 16; i++) { -+ unsigned char mask = pat[i]; -+ -+ if (!invert) { -+ chr[i ] = ((unsigned char*)VSHADOW1)[offset]; -+ chr[16 + i] = ((unsigned char*)VSHADOW2)[offset]; -+ chr[32 + i] = ((unsigned char*)VSHADOW4)[offset]; -+ chr[48 + i] = ((unsigned char*)VSHADOW8)[offset]; -+ -+ /* FIXME: if (shade) */ -+ if (1) { -+ if (ch == DISP_VERT || ch == DISP_LL || -+ ch == DISP_UR || ch == DISP_LR) { -+ unsigned char pmask = ~(pat[i] >> 1); -+ -+ chr[i ] &= pmask; -+ chr[16 + i] &= pmask; -+ chr[32 + i] &= pmask; -+ chr[48 + i] &= pmask; -+ } -+ if (i > 0 && ch != DISP_VERT) { -+ unsigned char pmask = ~(pat[i - 1] >> 1); -+ -+ chr[i ] &= pmask; -+ chr[16 + i] &= pmask; -+ chr[32 + i] &= pmask; -+ chr[48 + i] &= pmask; -+ if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) { -+ pmask = ~pat[i - 1]; -+ -+ chr[i ] &= pmask; -+ chr[16 + i] &= pmask; -+ chr[32 + i] &= pmask; -+ chr[48 + i] &= pmask; -+ } -+ } -+ } -+ chr[i ] |= mask; -+ chr[16 + i] |= mask; -+ chr[32 + i] |= mask; -+ chr[48 + i] |= mask; -+ -+ offset += 80; -+ } -+ else { -+ chr[i ] = mask; -+ chr[16 + i] = mask; -+ chr[32 + i] = mask; -+ chr[48 + i] = mask; -+ } -+ } -+ } -+ else { -+ MapMask(15); -+ ptr = mem; -+ for (i = 0; i < 16; i++, ptr += 80) { -+ cursorBuf[i] = pat[i]; -+ *ptr = ~pat[i]; -+ } -+ return; -+ } -+ -+ offset = 0; -+ for (i = 1; i < 16; i <<= 1, offset += 16) { -+ int j; -+ -+ MapMask(i); -+ ptr = mem; -+ for (j = 0; j < 16; j++, ptr += 80) -+ *ptr = chr[j + offset]; -+ } -+ -+ MapMask(15); -+} -+ -+int grub_file_exists(char *s) { -+ if (!grub_open(s)) -+ return 0; -+ grub_close(); -+ return 1; -+} -+ -+#endif /* SUPPORT_GRAPHICS */ -diff -Nur grub-0.97/stage2/graphics.h grub-0.97-patched/stage2/graphics.h ---- grub-0.97/stage2/graphics.h 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/stage2/graphics.h 2012-11-11 17:06:33.321470879 +0100 -@@ -0,0 +1,45 @@ -+/* graphics.h - graphics console interface */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002 Free Software Foundation, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * 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, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#ifndef GRAPHICS_H -+#define GRAPHICS_H -+ -+/* magic constant */ -+#define VIDEOMEM 0xA0000 -+ -+/* function prototypes */ -+char *graphics_get_splash(void); -+ -+int read_image(char *s); -+void graphics_cursor(int set); -+ -+/* function prototypes for asm functions */ -+void * graphics_get_font(); -+void graphics_set_palette(int idx, int red, int green, int blue); -+void set_int1c_handler(); -+void unset_int1c_handler(); -+ -+/* Only to check for safe opening before we start */ -+int grub_file_exists(char *s); -+ -+extern short cursorX, cursorY; -+extern char cursorBuf[16]; -+ -+#endif /* GRAPHICS_H */ -diff -Nur grub-0.97/stage2/iso9660.h grub-0.97-patched/stage2/iso9660.h ---- grub-0.97/stage2/iso9660.h 2004-03-27 17:02:38.000000000 +0100 -+++ grub-0.97-patched/stage2/iso9660.h 2012-11-11 17:07:12.740730013 +0100 -@@ -73,11 +73,11 @@ - - typedef struct __iso_16bit { - u_int16_t l, b; --} iso_16bit_t __attribute__ ((packed)); -+} iso_16bit_t; - - typedef struct __iso_32bit { - u_int32_t l, b; --} iso_32bit_t __attribute__ ((packed)); -+} iso_32bit_t; - - typedef u_int8_t iso_date_t[7]; - -diff -Nur grub-0.97/stage2/Makefile.am grub-0.97-patched/stage2/Makefile.am ---- grub-0.97/stage2/Makefile.am 2005-02-02 21:37:35.000000000 +0100 -+++ grub-0.97-patched/stage2/Makefile.am 2012-11-11 17:07:12.747730236 +0100 -@@ -7,7 +7,7 @@ - fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \ - imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \ - nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \ -- terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h -+ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h - EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS) - - # For <stage1.h>. -@@ -19,20 +19,20 @@ - disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \ - fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ - fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \ -- terminfo.c tparm.c --libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ -+ terminfo.c tparm.c graphics.c -+libgrub_a_CFLAGS = $(GRUB_CFLAGS) -fno-stack-protector -I$(top_srcdir)/lib \ - -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \ - -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \ - -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \ - -DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1 - - # Stage 2 and Stage 1.5's. --pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor) -+stagedir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor) - - EXTRA_PROGRAMS = nbloader.exec pxeloader.exec diskless.exec - - if DISKLESS_SUPPORT --pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ -+stage_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ - ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \ - reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \ - nbgrub pxegrub -@@ -43,7 +43,7 @@ - reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \ - xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec - else --pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ -+stage_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ - ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \ - reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 - noinst_DATA = pre_stage2 start start_eltorito -@@ -79,8 +79,14 @@ - HERCULES_FLAGS = - endif - --STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \ -- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) -+if GRAPHICS_SUPPORT -+GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1 -+else -+GRAPHICS_FLAGS = -+endif -+ -+STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-reorder-functions -fno-builtin -nostdinc \ -+ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS) - - STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 - STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 -@@ -90,7 +96,8 @@ - cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ - fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ - fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \ -- hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c -+ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \ -+ graphics.c - pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) - pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) - pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK) -@@ -105,7 +112,7 @@ - BUILT_SOURCES = stage2_size.h - endif - --CLEANFILES = $(pkglib_DATA) $(noinst_DATA) $(BUILT_SOURCES) -+CLEANFILES = $(stage_DATA) $(noinst_DATA) $(BUILT_SOURCES) - - stage2_size.h: pre_stage2 - -rm -f stage2_size.h -diff -Nur grub-0.97/stage2/Makefile.am.orig grub-0.97-patched/stage2/Makefile.am.orig ---- grub-0.97/stage2/Makefile.am.orig 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/stage2/Makefile.am.orig 2005-02-02 21:37:35.000000000 +0100 -@@ -0,0 +1,272 @@ -+# For test target. -+TESTS = size_test -+noinst_SCRIPTS = $(TESTS) -+ -+# For dist target. -+noinst_HEADERS = apic.h defs.h dir.h disk_inode.h disk_inode_ffs.h \ -+ fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \ -+ imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \ -+ nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \ -+ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h -+EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS) -+ -+# For <stage1.h>. -+INCLUDES = -I$(top_srcdir)/stage1 -+ -+# The library for /sbin/grub. -+noinst_LIBRARIES = libgrub.a -+libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \ -+ disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \ -+ fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ -+ fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \ -+ terminfo.c tparm.c -+libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ -+ -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \ -+ -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \ -+ -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \ -+ -DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1 -+ -+# Stage 2 and Stage 1.5's. -+pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor) -+ -+EXTRA_PROGRAMS = nbloader.exec pxeloader.exec diskless.exec -+ -+if DISKLESS_SUPPORT -+pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ -+ ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \ -+ reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \ -+ nbgrub pxegrub -+noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless -+noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \ -+ e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \ -+ iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \ -+ reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \ -+ xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec -+else -+pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \ -+ ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \ -+ reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 -+noinst_DATA = pre_stage2 start start_eltorito -+noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \ -+ e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \ -+ iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \ -+ reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \ -+ xfs_stage1_5.exec -+endif -+MOSTLYCLEANFILES = $(noinst_PROGRAMS) -+ -+PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200 -+START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000 -+NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0 -+PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 -+START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 -+ -+if NETBOOT_SUPPORT -+NETBOOT_FLAGS = -I$(top_srcdir)/netboot -DSUPPORT_NETBOOT=1 -+else -+NETBOOT_FLAGS = -+endif -+ -+if SERIAL_SUPPORT -+SERIAL_FLAGS = -DSUPPORT_SERIAL=1 -+else -+SERIAL_FLAGS = -+endif -+ -+if HERCULES_SUPPORT -+HERCULES_FLAGS = -DSUPPORT_HERCULES=1 -+else -+HERCULES_FLAGS = -+endif -+ -+STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \ -+ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) -+ -+STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 -+STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 -+ -+# For stage2 target. -+pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \ -+ cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ -+ fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ -+ fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \ -+ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c -+pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) -+pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) -+pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK) -+ -+if NETBOOT_SUPPORT -+pre_stage2_exec_LDADD = ../netboot/libdrivers.a -+endif -+ -+if DISKLESS_SUPPORT -+BUILT_SOURCES = stage2_size.h diskless_size.h -+else -+BUILT_SOURCES = stage2_size.h -+endif -+ -+CLEANFILES = $(pkglib_DATA) $(noinst_DATA) $(BUILT_SOURCES) -+ -+stage2_size.h: pre_stage2 -+ -rm -f stage2_size.h -+ set dummy `ls -l pre_stage2`; \ -+ echo "#define STAGE2_SIZE $$6" > stage2_size.h -+ -+start_exec_SOURCES = start.S -+start_exec_CCASFLAGS = $(STAGE2_COMPILE) -+start_exec_LDFLAGS = $(START_LINK) -+ -+# XXX: automake doesn't provide a way to specify dependencies for object -+# files explicitly, so we must write this by a general Makefile scheme. -+# If automake change the naming scheme for per-executable objects, this -+# will be broken. -+start_exec-start.$(OBJEXT): stage2_size.h -+ -+stage2: pre_stage2 start -+ -rm -f stage2 -+ cat start pre_stage2 > stage2 -+ -+start_eltorito_exec_SOURCES = start_eltorito.S -+start_eltorito_exec_CCASFLAGS = $(STAGE2_COMPILE) -+start_eltorito_exec_LDFLAGS = $(START_ELTORITO_LINK) -+ -+start_eltorito_exec-start.$(OBJEXT): stage2_size.h -+ -+stage2_eltorito: pre_stage2 start_eltorito -+ -rm -f stage2_eltorito -+ cat start_eltorito pre_stage2 > stage2_eltorito -+ -+# For e2fs_stage1_5 target. -+e2fs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \ -+ stage1_5.c fsys_ext2fs.c bios.c -+e2fs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_EXT2FS=1 \ -+ -DNO_BLOCK_FILES=1 -+e2fs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_EXT2FS=1 \ -+ -DNO_BLOCK_FILES=1 -+e2fs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For fat_stage1_5 target. -+fat_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \ -+ stage1_5.c fsys_fat.c bios.c -+fat_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FAT=1 \ -+ -DNO_BLOCK_FILES=1 -+fat_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FAT=1 \ -+ -DNO_BLOCK_FILES=1 -+fat_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For ffs_stage1_5 target. -+ffs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \ -+ stage1_5.c fsys_ffs.c bios.c -+ffs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \ -+ -DNO_BLOCK_FILES=1 -+ffs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \ -+ -DNO_BLOCK_FILES=1 -+ffs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For ufs2_stage1_5 target. -+ufs2_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \ -+ stage1_5.c fsys_ufs2.c bios.c -+ufs2_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \ -+ -DNO_BLOCK_FILES=1 -+ufs2_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \ -+ -DNO_BLOCK_FILES=1 -+ufs2_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For minix_stage1_5 target. -+minix_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \ -+ stage1_5.c fsys_minix.c bios.c -+minix_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_MINIX=1 \ -+ -DNO_BLOCK_FILES=1 -+minix_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_MINIX=1 \ -+ -DNO_BLOCK_FILES=1 -+minix_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For reiserfs_stage1_5 target. -+reiserfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \ -+ disk_io.c stage1_5.c fsys_reiserfs.c bios.c -+reiserfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_REISERFS=1 \ -+ -DNO_BLOCK_FILES=1 -+reiserfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_REISERFS=1 \ -+ -DNO_BLOCK_FILES=1 -+reiserfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For vstafs_stage1_5 target. -+vstafs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \ -+ disk_io.c stage1_5.c fsys_vstafs.c bios.c -+vstafs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_VSTAFS=1 \ -+ -DNO_BLOCK_FILES=1 -+vstafs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_VSTAFS=1 \ -+ -DNO_BLOCK_FILES=1 -+vstafs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For jfs_stage1_5 target. -+jfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \ -+ disk_io.c stage1_5.c fsys_jfs.c bios.c -+jfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_JFS=1 \ -+ -DNO_BLOCK_FILES=1 -+jfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_JFS=1 \ -+ -DNO_BLOCK_FILES=1 -+jfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For xfs_stage1_5 target. -+xfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \ -+ disk_io.c stage1_5.c fsys_xfs.c bios.c -+xfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_XFS=1 \ -+ -DNO_BLOCK_FILES=1 -+xfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_XFS=1 \ -+ -DNO_BLOCK_FILES=1 -+xfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For iso9660_stage1_5 target. -+iso9660_stage1_5_exec_SOURCES = start_eltorito.S asm.S common.c char_io.c \ -+ disk_io.c stage1_5.c fsys_iso9660.c bios.c -+iso9660_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ISO9660=1 \ -+ -DNO_BLOCK_FILES=1 -+iso9660_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ISO9660=1 \ -+ -DNO_BLOCK_FILES=1 -+iso9660_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK) -+ -+# For diskless target. -+diskless_exec_SOURCES = $(pre_stage2_exec_SOURCES) -+diskless_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \ -+ -DSUPPORT_DISKLESS=1 -+diskless_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \ -+ -DSUPPORT_DISKLESS=1 -+diskless_exec_LDFLAGS = $(PRE_STAGE2_LINK) -+diskless_exec_LDADD = ../netboot/libdrivers.a -+ -+diskless_size.h: diskless -+ -rm -f $@ -+ set dummy `ls -l $^`; \ -+ echo "#define DISKLESS_SIZE $$6" > $@ -+ -+# For nbloader target. -+nbloader_exec_SOURCES = nbloader.S -+nbloader_exec_CCASFLAGS = $(STAGE2_COMPILE) -+nbloader_exec_LDFLAGS = $(NBLOADER_LINK) -+ -+# XXX: See the comment for start_exec-start.o. -+nbloader_exec-nbloader.$(OBJEXT): diskless_size.h -+ -+# For nbgrub target. -+nbgrub: nbloader diskless -+ -rm -f $@ -+ cat $^ > $@ -+ -+# For pxeloader target. -+pxeloader_exec_SOURCES = pxeloader.S -+pxeloader_exec_CCASFLAGS = $(STAGE2_COMPILE) -+pxeloader_exec_LDFLAGS = $(PXELOADER_LINK) -+ -+# XXX: See the comment for start_exec-start.o. -+pxeloader_exec-pxeloader.$(OBJEXT): diskless_size.h -+ -+# For pxegrub target. -+pxegrub: pxeloader diskless -+ -rm -f $@ -+ cat $^ > $@ -+ -+# General rule for making a raw binary. -+SUFFIXES = .exec -+.exec: -+ $(OBJCOPY) -O binary $< $@ -diff -Nur grub-0.97/stage2/pc_slice.h grub-0.97-patched/stage2/pc_slice.h ---- grub-0.97/stage2/pc_slice.h 2003-07-09 13:45:53.000000000 +0200 -+++ grub-0.97-patched/stage2/pc_slice.h 2012-11-11 17:07:12.698728671 +0100 -@@ -115,6 +115,7 @@ - #define PC_SLICE_TYPE_LINUX_EXTENDED 0x85 - #define PC_SLICE_TYPE_VSTAFS 0x9e - #define PC_SLICE_TYPE_DELL_UTIL 0xde -+#define PC_SLICE_TYPE_GPT 0xee - #define PC_SLICE_TYPE_LINUX_RAID 0xfd - - -diff -Nur grub-0.97/stage2/shared.h grub-0.97-patched/stage2/shared.h ---- grub-0.97/stage2/shared.h 2004-06-19 18:40:09.000000000 +0200 -+++ grub-0.97-patched/stage2/shared.h 2012-11-11 17:07:12.741730044 +0100 -@@ -36,8 +36,8 @@ - - /* Maybe redirect memory requests through grub_scratch_mem. */ - #ifdef GRUB_UTIL --extern char *grub_scratch_mem; --# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem) -+extern void *grub_scratch_mem; -+# define RAW_ADDR(x) ((x) + (unsigned long) grub_scratch_mem) - # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4) - #else - # define RAW_ADDR(x) (x) -@@ -161,7 +161,9 @@ - - #define LINUX_CL_OFFSET 0x9000 - #define LINUX_CL_END_OFFSET 0x90FF --#define LINUX_SETUP_MOVE_SIZE 0x9100 -+#define LINUX_CL_0202_PRM_OFFSET 0x9500 -+#define LINUX_CL_0202_PRM_END_OFFSET 0x9FFF -+#define LINUX_SETUP_MOVE_SIZE 0xA000 - #define LINUX_CL_MAGIC 0xA33F - - /* -@@ -499,7 +501,11 @@ - unsigned char linear_reserved_field_position; - unsigned long max_pixel_clock; - -- unsigned char reserved3[189]; -+ /* Reserved field to make structure to be 256 bytes long, VESA BIOS -+ Extension 3.0 Specification says to reserve 189 bytes here but -+ that doesn't make structure to be 256 bytes. So additional one is -+ added here. */ -+ unsigned char reserved3[189 + 1]; - } __attribute__ ((packed)); - - -@@ -807,7 +813,7 @@ - /* Low-level disk I/O */ - int get_diskinfo (int drive, struct geometry *geometry); - int biosdisk (int subfunc, int drive, struct geometry *geometry, -- int sector, int nsec, int segment); -+ unsigned int sector, int nsec, int segment); - void stop_floppy (void); - - /* Command-line interface functions. */ -@@ -871,6 +877,7 @@ - int grub_tolower (int c); - int grub_isspace (int c); - int grub_strncat (char *s1, const char *s2, int n); -+void grub_memcpy(void *dest, const void *src, int len); - void *grub_memmove (void *to, const void *from, int len); - void *grub_memset (void *start, int c, int len); - int grub_strncat (char *s1, const char *s2, int n); -@@ -911,7 +918,7 @@ - int nul_terminate (char *str); - int get_based_digit (int c, int base); - int safe_parse_maxint (char **str_ptr, int *myint_ptr); --int memcheck (int start, int len); -+int memcheck (unsigned long start, unsigned long len); - void grub_putstr (const char *str); - - #ifndef NO_DECOMPRESSION -@@ -920,10 +927,10 @@ - int gunzip_read (char *buf, int len); - #endif /* NO_DECOMPRESSION */ - --int rawread (int drive, int sector, int byte_offset, int byte_len, char *buf); --int devread (int sector, int byte_offset, int byte_len, char *buf); --int rawwrite (int drive, int sector, char *buf); --int devwrite (int sector, int sector_len, char *buf); -+int rawread (int drive, unsigned int sector, int byte_offset, int byte_len, char *buf); -+int devread (unsigned int sector, int byte_offset, int byte_len, char *buf); -+int rawwrite (int drive, unsigned int sector, char *buf); -+int devwrite (unsigned int sector, int sector_len, char *buf); - - /* Parse a device string and initialize the global parameters. */ - char *set_device (char *device); -@@ -934,7 +941,9 @@ - unsigned long *partition, int *type, - unsigned long *start, unsigned long *len, - unsigned long *offset, int *entry, -- unsigned long *ext_offset, char *buf); -+ unsigned long *ext_offset, -+ unsigned long *gpt_offset, int *gpt_count, -+ int *gpt_size, char *buf); - - /* Sets device to the one represented by the SAVED_* parameters. */ - int make_saved_active (void); -diff -Nur grub-0.97/stage2/size_test grub-0.97-patched/stage2/size_test ---- grub-0.97/stage2/size_test 2004-05-14 21:30:52.000000000 +0200 -+++ grub-0.97-patched/stage2/size_test 2012-11-11 17:06:52.554085177 +0100 -@@ -36,9 +36,9 @@ - } - - # The bootloader area of a FFS partition is 14 sectors. --check ffs_stage1_5 7168 -- --check ufs2_stage1_5 7168 -+#check ffs_stage1_5 7168 -+# -+#check ufs2_stage1_5 7168 - - # Stage 1.5 can be installed in the sectors immediately after MBR in the - # first cylinder, so the size is (63 - 1) sectors. -diff -Nur grub-0.97/stage2/stage2.c grub-0.97-patched/stage2/stage2.c ---- grub-0.97/stage2/stage2.c 2005-03-19 18:51:57.000000000 +0100 -+++ grub-0.97-patched/stage2/stage2.c 2012-11-11 17:07:12.742730076 +0100 -@@ -233,6 +233,7 @@ - { - int c, time1, time2 = -1, first_entry = 0; - char *cur_entry = 0; -+ struct term_entry *prev_term = NULL; - - /* - * Main loop for menu UI. -@@ -651,7 +652,10 @@ - *(new_heap++) = 0; - - if (config_entries) -- run_menu (heap, NULL, new_num_entries, new_heap, 0); -+ { -+ current_entryno = first_entry + entryno; -+ run_menu (heap, NULL, new_num_entries, new_heap, 0); -+ } - else - { - cls (); -@@ -714,6 +718,15 @@ - - cls (); - setcursor (1); -+ /* if our terminal needed initialization, we should shut it down -+ * before booting the kernel, but we want to save what it was so -+ * we can come back if needed */ -+ prev_term = current_term; -+ if (current_term->shutdown) -+ { -+ (*current_term->shutdown)(); -+ current_term = term_table; /* assumption: console is first */ -+ } - - while (1) - { -@@ -727,7 +740,8 @@ - cur_entry = get_entry (config_entries, first_entry + entryno, 1); - - /* Set CURRENT_ENTRYNO for the command "savedefault". */ -- current_entryno = first_entry + entryno; -+ if (config_entries) -+ current_entryno = first_entry + entryno; - - if (run_script (cur_entry, heap)) - { -@@ -748,6 +762,13 @@ - break; - } - -+ /* if we get back here, we should go back to what our term was before */ -+ current_term = prev_term; -+ if (current_term->startup) -+ /* if our terminal fails to initialize, fall back to console since -+ * it should always work */ -+ if ((*current_term->startup)() == 0) -+ current_term = term_table; /* we know that console is first */ - show_menu = 1; - goto restart; - } -@@ -1050,6 +1071,10 @@ - while (is_preset); - } - -+ /* go ahead and make sure the terminal is setup */ -+ if (current_term->startup) -+ (*current_term->startup)(); -+ - if (! num_entries) - { - /* If no acceptable config file, goto command-line, starting -diff -Nur grub-0.97/stage2/stage2.c.orig grub-0.97-patched/stage2/stage2.c.orig ---- grub-0.97/stage2/stage2.c.orig 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/stage2/stage2.c.orig 2005-03-19 18:51:57.000000000 +0100 -@@ -0,0 +1,1067 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2000,2001,2002,2004,2005 Free Software Foundation, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * 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, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include <shared.h> -+#include <term.h> -+ -+grub_jmp_buf restart_env; -+ -+#if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) -+ -+# if defined(PRESET_MENU_STRING) -+static const char *preset_menu = PRESET_MENU_STRING; -+# elif defined(SUPPORT_DISKLESS) -+/* Execute the command "bootp" automatically. */ -+static const char *preset_menu = "bootp\n"; -+# endif /* SUPPORT_DISKLESS */ -+ -+static int preset_menu_offset; -+ -+static int -+open_preset_menu (void) -+{ -+#ifdef GRUB_UTIL -+ /* Unless the user explicitly requests to use the preset menu, -+ always opening the preset menu fails in the grub shell. */ -+ if (! use_preset_menu) -+ return 0; -+#endif /* GRUB_UTIL */ -+ -+ preset_menu_offset = 0; -+ return preset_menu != 0; -+} -+ -+static int -+read_from_preset_menu (char *buf, int maxlen) -+{ -+ int len = grub_strlen (preset_menu + preset_menu_offset); -+ -+ if (len > maxlen) -+ len = maxlen; -+ -+ grub_memmove (buf, preset_menu + preset_menu_offset, len); -+ preset_menu_offset += len; -+ -+ return len; -+} -+ -+static void -+close_preset_menu (void) -+{ -+ /* Disable the preset menu. */ -+ preset_menu = 0; -+} -+ -+#else /* ! PRESET_MENU_STRING && ! SUPPORT_DISKLESS */ -+ -+#define open_preset_menu() 0 -+#define read_from_preset_menu(buf, maxlen) 0 -+#define close_preset_menu() -+ -+#endif /* ! PRESET_MENU_STRING && ! SUPPORT_DISKLESS */ -+ -+static char * -+get_entry (char *list, int num, int nested) -+{ -+ int i; -+ -+ for (i = 0; i < num; i++) -+ { -+ do -+ { -+ while (*(list++)); -+ } -+ while (nested && *(list++)); -+ } -+ -+ return list; -+} -+ -+/* Print an entry in a line of the menu box. */ -+static void -+print_entry (int y, int highlight, char *entry) -+{ -+ int x; -+ -+ if (current_term->setcolorstate) -+ current_term->setcolorstate (COLOR_STATE_NORMAL); -+ -+ if (highlight && current_term->setcolorstate) -+ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); -+ -+ gotoxy (2, y); -+ grub_putchar (' '); -+ for (x = 3; x < 75; x++) -+ { -+ if (*entry && x <= 72) -+ { -+ if (x == 72) -+ grub_putchar (DISP_RIGHT); -+ else -+ grub_putchar (*entry++); -+ } -+ else -+ grub_putchar (' '); -+ } -+ gotoxy (74, y); -+ -+ if (current_term->setcolorstate) -+ current_term->setcolorstate (COLOR_STATE_STANDARD); -+} -+ -+/* Print entries in the menu box. */ -+static void -+print_entries (int y, int size, int first, int entryno, char *menu_entries) -+{ -+ int i; -+ -+ gotoxy (77, y + 1); -+ -+ if (first) -+ grub_putchar (DISP_UP); -+ else -+ grub_putchar (' '); -+ -+ menu_entries = get_entry (menu_entries, first, 0); -+ -+ for (i = 0; i < size; i++) -+ { -+ print_entry (y + i + 1, entryno == i, menu_entries); -+ -+ while (*menu_entries) -+ menu_entries++; -+ -+ if (*(menu_entries - 1)) -+ menu_entries++; -+ } -+ -+ gotoxy (77, y + size); -+ -+ if (*menu_entries) -+ grub_putchar (DISP_DOWN); -+ else -+ grub_putchar (' '); -+ -+ gotoxy (74, y + entryno + 1); -+} -+ -+static void -+print_entries_raw (int size, int first, char *menu_entries) -+{ -+ int i; -+ -+#define LINE_LENGTH 67 -+ -+ for (i = 0; i < LINE_LENGTH; i++) -+ grub_putchar ('-'); -+ grub_putchar ('\n'); -+ -+ for (i = first; i < size; i++) -+ { -+ /* grub's printf can't %02d so ... */ -+ if (i < 10) -+ grub_putchar (' '); -+ grub_printf ("%d: %s\n", i, get_entry (menu_entries, i, 0)); -+ } -+ -+ for (i = 0; i < LINE_LENGTH; i++) -+ grub_putchar ('-'); -+ grub_putchar ('\n'); -+ -+#undef LINE_LENGTH -+} -+ -+ -+static void -+print_border (int y, int size) -+{ -+ int i; -+ -+ if (current_term->setcolorstate) -+ current_term->setcolorstate (COLOR_STATE_NORMAL); -+ -+ gotoxy (1, y); -+ -+ grub_putchar (DISP_UL); -+ for (i = 0; i < 73; i++) -+ grub_putchar (DISP_HORIZ); -+ grub_putchar (DISP_UR); -+ -+ i = 1; -+ while (1) -+ { -+ gotoxy (1, y + i); -+ -+ if (i > size) -+ break; -+ -+ grub_putchar (DISP_VERT); -+ gotoxy (75, y + i); -+ grub_putchar (DISP_VERT); -+ -+ i++; -+ } -+ -+ grub_putchar (DISP_LL); -+ for (i = 0; i < 73; i++) -+ grub_putchar (DISP_HORIZ); -+ grub_putchar (DISP_LR); -+ -+ if (current_term->setcolorstate) -+ current_term->setcolorstate (COLOR_STATE_STANDARD); -+} -+ -+static void -+run_menu (char *menu_entries, char *config_entries, int num_entries, -+ char *heap, int entryno) -+{ -+ int c, time1, time2 = -1, first_entry = 0; -+ char *cur_entry = 0; -+ -+ /* -+ * Main loop for menu UI. -+ */ -+ -+restart: -+ /* Dumb terminal always use all entries for display -+ invariant for TERM_DUMB: first_entry == 0 */ -+ if (! (current_term->flags & TERM_DUMB)) -+ { -+ while (entryno > 11) -+ { -+ first_entry++; -+ entryno--; -+ } -+ } -+ -+ /* If the timeout was expired or wasn't set, force to show the menu -+ interface. */ -+ if (grub_timeout < 0) -+ show_menu = 1; -+ -+ /* If SHOW_MENU is false, don't display the menu until ESC is pressed. */ -+ if (! show_menu) -+ { -+ /* Get current time. */ -+ while ((time1 = getrtsecs ()) == 0xFF) -+ ; -+ -+ while (1) -+ { -+ /* Check if ESC is pressed. */ -+ if (checkkey () != -1 && ASCII_CHAR (getkey ()) == '\e') -+ { -+ grub_timeout = -1; -+ show_menu = 1; -+ break; -+ } -+ -+ /* If GRUB_TIMEOUT is expired, boot the default entry. */ -+ if (grub_timeout >=0 -+ && (time1 = getrtsecs ()) != time2 -+ && time1 != 0xFF) -+ { -+ if (grub_timeout <= 0) -+ { -+ grub_timeout = -1; -+ goto boot_entry; -+ } -+ -+ time2 = time1; -+ grub_timeout--; -+ -+ /* Print a message. */ -+ grub_printf ("\rPress `ESC' to enter the menu... %d ", -+ grub_timeout); -+ } -+ } -+ } -+ -+ /* Only display the menu if the user wants to see it. */ -+ if (show_menu) -+ { -+ init_page (); -+ setcursor (0); -+ -+ if (current_term->flags & TERM_DUMB) -+ print_entries_raw (num_entries, first_entry, menu_entries); -+ else -+ print_border (3, 12); -+ -+ grub_printf ("\n\ -+ Use the %c and %c keys to select which entry is highlighted.\n", -+ DISP_UP, DISP_DOWN); -+ -+ if (! auth && password) -+ { -+ printf ("\ -+ Press enter to boot the selected OS or 'p' to enter a\n\ -+ password to unlock the next set of features."); -+ } -+ else -+ { -+ if (config_entries) -+ printf ("\ -+ Press enter to boot the selected OS, 'e' to edit the\n\ -+ commands before booting, or 'c' for a command-line."); -+ else -+ printf ("\ -+ Press 'b' to boot, 'e' to edit the selected command in the\n\ -+ boot sequence, 'c' for a command-line, 'o' to open a new line\n\ -+ after ('O' for before) the selected line, 'd' to remove the\n\ -+ selected line, or escape to go back to the main menu."); -+ } -+ -+ if (current_term->flags & TERM_DUMB) -+ grub_printf ("\n\nThe selected entry is %d ", entryno); -+ else -+ print_entries (3, 12, first_entry, entryno, menu_entries); -+ } -+ -+ /* XX using RT clock now, need to initialize value */ -+ while ((time1 = getrtsecs()) == 0xFF); -+ -+ while (1) -+ { -+ /* Initialize to NULL just in case... */ -+ cur_entry = NULL; -+ -+ if (grub_timeout >= 0 && (time1 = getrtsecs()) != time2 && time1 != 0xFF) -+ { -+ if (grub_timeout <= 0) -+ { -+ grub_timeout = -1; -+ break; -+ } -+ -+ /* else not booting yet! */ -+ time2 = time1; -+ -+ if (current_term->flags & TERM_DUMB) -+ grub_printf ("\r Entry %d will be booted automatically in %d seconds. ", -+ entryno, grub_timeout); -+ else -+ { -+ gotoxy (3, 22); -+ grub_printf ("The highlighted entry will be booted automatically in %d seconds. ", -+ grub_timeout); -+ gotoxy (74, 4 + entryno); -+ } -+ -+ grub_timeout--; -+ } -+ -+ /* Check for a keypress, however if TIMEOUT has been expired -+ (GRUB_TIMEOUT == -1) relax in GETKEY even if no key has been -+ pressed. -+ This avoids polling (relevant in the grub-shell and later on -+ in grub if interrupt driven I/O is done). */ -+ if (checkkey () >= 0 || grub_timeout < 0) -+ { -+ /* Key was pressed, show which entry is selected before GETKEY, -+ since we're comming in here also on GRUB_TIMEOUT == -1 and -+ hang in GETKEY */ -+ if (current_term->flags & TERM_DUMB) -+ grub_printf ("\r Highlighted entry is %d: ", entryno); -+ -+ c = ASCII_CHAR (getkey ()); -+ -+ if (grub_timeout >= 0) -+ { -+ if (current_term->flags & TERM_DUMB) -+ grub_putchar ('\r'); -+ else -+ gotoxy (3, 22); -+ printf (" "); -+ grub_timeout = -1; -+ fallback_entryno = -1; -+ if (! (current_term->flags & TERM_DUMB)) -+ gotoxy (74, 4 + entryno); -+ } -+ -+ /* We told them above (at least in SUPPORT_SERIAL) to use -+ '^' or 'v' so accept these keys. */ -+ if (c == 16 || c == '^') -+ { -+ if (current_term->flags & TERM_DUMB) -+ { -+ if (entryno > 0) -+ entryno--; -+ } -+ else -+ { -+ if (entryno > 0) -+ { -+ print_entry (4 + entryno, 0, -+ get_entry (menu_entries, -+ first_entry + entryno, -+ 0)); -+ entryno--; -+ print_entry (4 + entryno, 1, -+ get_entry (menu_entries, -+ first_entry + entryno, -+ 0)); -+ } -+ else if (first_entry > 0) -+ { -+ first_entry--; -+ print_entries (3, 12, first_entry, entryno, -+ menu_entries); -+ } -+ } -+ } -+ else if ((c == 14 || c == 'v') -+ && first_entry + entryno + 1 < num_entries) -+ { -+ if (current_term->flags & TERM_DUMB) -+ entryno++; -+ else -+ { -+ if (entryno < 11) -+ { -+ print_entry (4 + entryno, 0, -+ get_entry (menu_entries, -+ first_entry + entryno, -+ 0)); -+ entryno++; -+ print_entry (4 + entryno, 1, -+ get_entry (menu_entries, -+ first_entry + entryno, -+ 0)); -+ } -+ else if (num_entries > 12 + first_entry) -+ { -+ first_entry++; -+ print_entries (3, 12, first_entry, entryno, menu_entries); -+ } -+ } -+ } -+ else if (c == 7) -+ { -+ /* Page Up */ -+ first_entry -= 12; -+ if (first_entry < 0) -+ { -+ entryno += first_entry; -+ first_entry = 0; -+ if (entryno < 0) -+ entryno = 0; -+ } -+ print_entries (3, 12, first_entry, entryno, menu_entries); -+ } -+ else if (c == 3) -+ { -+ /* Page Down */ -+ first_entry += 12; -+ if (first_entry + entryno + 1 >= num_entries) -+ { -+ first_entry = num_entries - 12; -+ if (first_entry < 0) -+ first_entry = 0; -+ entryno = num_entries - first_entry - 1; -+ } -+ print_entries (3, 12, first_entry, entryno, menu_entries); -+ } -+ -+ if (config_entries) -+ { -+ if ((c == '\n') || (c == '\r') || (c == 6)) -+ break; -+ } -+ else -+ { -+ if ((c == 'd') || (c == 'o') || (c == 'O')) -+ { -+ if (! (current_term->flags & TERM_DUMB)) -+ print_entry (4 + entryno, 0, -+ get_entry (menu_entries, -+ first_entry + entryno, -+ 0)); -+ -+ /* insert after is almost exactly like insert before */ -+ if (c == 'o') -+ { -+ /* But `o' differs from `O', since it may causes -+ the menu screen to scroll up. */ -+ if (entryno < 11 || (current_term->flags & TERM_DUMB)) -+ entryno++; -+ else -+ first_entry++; -+ -+ c = 'O'; -+ } -+ -+ cur_entry = get_entry (menu_entries, -+ first_entry + entryno, -+ 0); -+ -+ if (c == 'O') -+ { -+ grub_memmove (cur_entry + 2, cur_entry, -+ ((int) heap) - ((int) cur_entry)); -+ -+ cur_entry[0] = ' '; -+ cur_entry[1] = 0; -+ -+ heap += 2; -+ -+ num_entries++; -+ } -+ else if (num_entries > 0) -+ { -+ char *ptr = get_entry(menu_entries, -+ first_entry + entryno + 1, -+ 0); -+ -+ grub_memmove (cur_entry, ptr, -+ ((int) heap) - ((int) ptr)); -+ heap -= (((int) ptr) - ((int) cur_entry)); -+ -+ num_entries--; -+ -+ if (entryno >= num_entries) -+ entryno--; -+ if (first_entry && num_entries < 12 + first_entry) -+ first_entry--; -+ } -+ -+ if (current_term->flags & TERM_DUMB) -+ { -+ grub_printf ("\n\n"); -+ print_entries_raw (num_entries, first_entry, -+ menu_entries); -+ grub_printf ("\n"); -+ } -+ else -+ print_entries (3, 12, first_entry, entryno, menu_entries); -+ } -+ -+ cur_entry = menu_entries; -+ if (c == 27) -+ return; -+ if (c == 'b') -+ break; -+ } -+ -+ if (! auth && password) -+ { -+ if (c == 'p') -+ { -+ /* Do password check here! */ -+ char entered[32]; -+ char *pptr = password; -+ -+ if (current_term->flags & TERM_DUMB) -+ grub_printf ("\r "); -+ else -+ gotoxy (1, 21); -+ -+ /* Wipe out the previously entered password */ -+ grub_memset (entered, 0, sizeof (entered)); -+ get_cmdline (" Password: ", entered, 31, '*', 0); -+ -+ while (! isspace (*pptr) && *pptr) -+ pptr++; -+ -+ /* Make sure that PASSWORD is NUL-terminated. */ -+ *pptr++ = 0; -+ -+ if (! check_password (entered, password, password_type)) -+ { -+ char *new_file = config_file; -+ while (isspace (*pptr)) -+ pptr++; -+ -+ /* If *PPTR is NUL, then allow the user to use -+ privileged instructions, otherwise, load -+ another configuration file. */ -+ if (*pptr != 0) -+ { -+ while ((*(new_file++) = *(pptr++)) != 0) -+ ; -+ -+ /* Make sure that the user will not have -+ authority in the next configuration. */ -+ auth = 0; -+ return; -+ } -+ else -+ { -+ /* Now the user is superhuman. */ -+ auth = 1; -+ goto restart; -+ } -+ } -+ else -+ { -+ grub_printf ("Failed!\n Press any key to continue..."); -+ getkey (); -+ goto restart; -+ } -+ } -+ } -+ else -+ { -+ if (c == 'e') -+ { -+ int new_num_entries = 0, i = 0; -+ char *new_heap; -+ -+ if (config_entries) -+ { -+ new_heap = heap; -+ cur_entry = get_entry (config_entries, -+ first_entry + entryno, -+ 1); -+ } -+ else -+ { -+ /* safe area! */ -+ new_heap = heap + NEW_HEAPSIZE + 1; -+ cur_entry = get_entry (menu_entries, -+ first_entry + entryno, -+ 0); -+ } -+ -+ do -+ { -+ while ((*(new_heap++) = cur_entry[i++]) != 0); -+ new_num_entries++; -+ } -+ while (config_entries && cur_entry[i]); -+ -+ /* this only needs to be done if config_entries is non-NULL, -+ but it doesn't hurt to do it always */ -+ *(new_heap++) = 0; -+ -+ if (config_entries) -+ run_menu (heap, NULL, new_num_entries, new_heap, 0); -+ else -+ { -+ cls (); -+ print_cmdline_message (0); -+ -+ new_heap = heap + NEW_HEAPSIZE + 1; -+ -+ saved_drive = boot_drive; -+ saved_partition = install_partition; -+ current_drive = GRUB_INVALID_DRIVE; -+ -+ if (! get_cmdline (PACKAGE " edit> ", new_heap, -+ NEW_HEAPSIZE + 1, 0, 1)) -+ { -+ int j = 0; -+ -+ /* get length of new command */ -+ while (new_heap[j++]) -+ ; -+ -+ if (j < 2) -+ { -+ j = 2; -+ new_heap[0] = ' '; -+ new_heap[1] = 0; -+ } -+ -+ /* align rest of commands properly */ -+ grub_memmove (cur_entry + j, cur_entry + i, -+ (int) heap - ((int) cur_entry + i)); -+ -+ /* copy command to correct area */ -+ grub_memmove (cur_entry, new_heap, j); -+ -+ heap += (j - i); -+ } -+ } -+ -+ goto restart; -+ } -+ if (c == 'c') -+ { -+ enter_cmdline (heap, 0); -+ goto restart; -+ } -+#ifdef GRUB_UTIL -+ if (c == 'q') -+ { -+ /* The same as ``quit''. */ -+ stop (); -+ } -+#endif -+ } -+ } -+ } -+ -+ /* Attempt to boot an entry. */ -+ -+ boot_entry: -+ -+ cls (); -+ setcursor (1); -+ -+ while (1) -+ { -+ if (config_entries) -+ printf (" Booting '%s'\n\n", -+ get_entry (menu_entries, first_entry + entryno, 0)); -+ else -+ printf (" Booting command-list\n\n"); -+ -+ if (! cur_entry) -+ cur_entry = get_entry (config_entries, first_entry + entryno, 1); -+ -+ /* Set CURRENT_ENTRYNO for the command "savedefault". */ -+ current_entryno = first_entry + entryno; -+ -+ if (run_script (cur_entry, heap)) -+ { -+ if (fallback_entryno >= 0) -+ { -+ cur_entry = NULL; -+ first_entry = 0; -+ entryno = fallback_entries[fallback_entryno]; -+ fallback_entryno++; -+ if (fallback_entryno >= MAX_FALLBACK_ENTRIES -+ || fallback_entries[fallback_entryno] < 0) -+ fallback_entryno = -1; -+ } -+ else -+ break; -+ } -+ else -+ break; -+ } -+ -+ show_menu = 1; -+ goto restart; -+} -+ -+ -+static int -+get_line_from_config (char *cmdline, int maxlen, int read_from_file) -+{ -+ int pos = 0, literal = 0, comment = 0; -+ char c; /* since we're loading it a byte at a time! */ -+ -+ while (1) -+ { -+ if (read_from_file) -+ { -+ if (! grub_read (&c, 1)) -+ break; -+ } -+ else -+ { -+ if (! read_from_preset_menu (&c, 1)) -+ break; -+ } -+ -+ /* Skip all carriage returns. */ -+ if (c == '\r') -+ continue; -+ -+ /* Replace tabs with spaces. */ -+ if (c == '\t') -+ c = ' '; -+ -+ /* The previous is a backslash, then... */ -+ if (literal) -+ { -+ /* If it is a newline, replace it with a space and continue. */ -+ if (c == '\n') -+ { -+ c = ' '; -+ -+ /* Go back to overwrite a backslash. */ -+ if (pos > 0) -+ pos--; -+ } -+ -+ literal = 0; -+ } -+ -+ /* translate characters first! */ -+ if (c == '\' && ! literal) -+ literal = 1; -+ -+ if (comment) -+ { -+ if (c == '\n') -+ comment = 0; -+ } -+ else if (! pos) -+ { -+ if (c == '#') -+ comment = 1; -+ else if ((c != ' ') && (c != '\n')) -+ cmdline[pos++] = c; -+ } -+ else -+ { -+ if (c == '\n') -+ break; -+ -+ if (pos < maxlen) -+ cmdline[pos++] = c; -+ } -+ } -+ -+ cmdline[pos] = 0; -+ -+ return pos; -+} -+ -+ -+/* This is the starting function in C. */ -+void -+cmain (void) -+{ -+ int config_len, menu_len, num_entries; -+ char *config_entries, *menu_entries; -+ char *kill_buf = (char *) KILL_BUF; -+ -+ auto void reset (void); -+ void reset (void) -+ { -+ count_lines = -1; -+ config_len = 0; -+ menu_len = 0; -+ num_entries = 0; -+ config_entries = (char *) mbi.drives_addr + mbi.drives_length; -+ menu_entries = (char *) MENU_BUF; -+ init_config (); -+ } -+ -+ /* Initialize the environment for restarting Stage 2. */ -+ grub_setjmp (restart_env); -+ -+ /* Initialize the kill buffer. */ -+ *kill_buf = 0; -+ -+ /* Never return. */ -+ for (;;) -+ { -+ int is_opened, is_preset; -+ -+ reset (); -+ -+ /* Here load the configuration file. */ -+ -+#ifdef GRUB_UTIL -+ if (use_config_file) -+#endif /* GRUB_UTIL */ -+ { -+ char *default_file = (char *) DEFAULT_FILE_BUF; -+ int i; -+ -+ /* Get a saved default entry if possible. */ -+ saved_entryno = 0; -+ *default_file = 0; -+ grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN); -+ for (i = grub_strlen(default_file); i >= 0; i--) -+ if (default_file[i] == '/') -+ { -+ i++; -+ break; -+ } -+ default_file[i] = 0; -+ grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i); -+ if (grub_open (default_file)) -+ { -+ char buf[10]; /* This is good enough. */ -+ char *p = buf; -+ int len; -+ -+ len = grub_read (buf, sizeof (buf)); -+ if (len > 0) -+ { -+ buf[sizeof (buf) - 1] = 0; -+ safe_parse_maxint (&p, &saved_entryno); -+ } -+ -+ grub_close (); -+ } -+ errnum = ERR_NONE; -+ -+ do -+ { -+ /* STATE 0: Before any title command. -+ STATE 1: In a title command. -+ STATE >1: In a entry after a title command. */ -+ int state = 0, prev_config_len = 0, prev_menu_len = 0; -+ char *cmdline; -+ -+ /* Try the preset menu first. This will succeed at most once, -+ because close_preset_menu disables the preset menu. */ -+ is_opened = is_preset = open_preset_menu (); -+ if (! is_opened) -+ { -+ is_opened = grub_open (config_file); -+ errnum = ERR_NONE; -+ } -+ -+ if (! is_opened) -+ break; -+ -+ /* This is necessary, because the menu must be overrided. */ -+ reset (); -+ -+ cmdline = (char *) CMDLINE_BUF; -+ while (get_line_from_config (cmdline, NEW_HEAPSIZE, -+ ! is_preset)) -+ { -+ struct builtin *builtin; -+ -+ /* Get the pointer to the builtin structure. */ -+ builtin = find_command (cmdline); -+ errnum = 0; -+ if (! builtin) -+ /* Unknown command. Just skip now. */ -+ continue; -+ -+ if (builtin->flags & BUILTIN_TITLE) -+ { -+ char *ptr; -+ -+ /* the command "title" is specially treated. */ -+ if (state > 1) -+ { -+ /* The next title is found. */ -+ num_entries++; -+ config_entries[config_len++] = 0; -+ prev_menu_len = menu_len; -+ prev_config_len = config_len; -+ } -+ else -+ { -+ /* The first title is found. */ -+ menu_len = prev_menu_len; -+ config_len = prev_config_len; -+ } -+ -+ /* Reset the state. */ -+ state = 1; -+ -+ /* Copy title into menu area. */ -+ ptr = skip_to (1, cmdline); -+ while ((menu_entries[menu_len++] = *(ptr++)) != 0) -+ ; -+ } -+ else if (! state) -+ { -+ /* Run a command found is possible. */ -+ if (builtin->flags & BUILTIN_MENU) -+ { -+ char *arg = skip_to (1, cmdline); -+ (builtin->func) (arg, BUILTIN_MENU); -+ errnum = 0; -+ } -+ else -+ /* Ignored. */ -+ continue; -+ } -+ else -+ { -+ char *ptr = cmdline; -+ -+ state++; -+ /* Copy config file data to config area. */ -+ while ((config_entries[config_len++] = *ptr++) != 0) -+ ; -+ } -+ } -+ -+ if (state > 1) -+ { -+ /* Finish the last entry. */ -+ num_entries++; -+ config_entries[config_len++] = 0; -+ } -+ else -+ { -+ menu_len = prev_menu_len; -+ config_len = prev_config_len; -+ } -+ -+ menu_entries[menu_len++] = 0; -+ config_entries[config_len++] = 0; -+ grub_memmove (config_entries + config_len, menu_entries, -+ menu_len); -+ menu_entries = config_entries + config_len; -+ -+ /* Make sure that all fallback entries are valid. */ -+ if (fallback_entryno >= 0) -+ { -+ for (i = 0; i < MAX_FALLBACK_ENTRIES; i++) -+ { -+ if (fallback_entries[i] < 0) -+ break; -+ if (fallback_entries[i] >= num_entries) -+ { -+ grub_memmove (fallback_entries + i, -+ fallback_entries + i + 1, -+ ((MAX_FALLBACK_ENTRIES - i - 1) -+ * sizeof (int))); -+ i--; -+ } -+ } -+ -+ if (fallback_entries[0] < 0) -+ fallback_entryno = -1; -+ } -+ /* Check if the default entry is present. Otherwise reset -+ it to fallback if fallback is valid, or to DEFAULT_ENTRY -+ if not. */ -+ if (default_entry >= num_entries) -+ { -+ if (fallback_entryno >= 0) -+ { -+ default_entry = fallback_entries[0]; -+ fallback_entryno++; -+ if (fallback_entryno >= MAX_FALLBACK_ENTRIES -+ || fallback_entries[fallback_entryno] < 0) -+ fallback_entryno = -1; -+ } -+ else -+ default_entry = 0; -+ } -+ -+ if (is_preset) -+ close_preset_menu (); -+ else -+ grub_close (); -+ } -+ while (is_preset); -+ } -+ -+ if (! num_entries) -+ { -+ /* If no acceptable config file, goto command-line, starting -+ heap from where the config entries would have been stored -+ if there were any. */ -+ enter_cmdline (config_entries, 1); -+ } -+ else -+ { -+ /* Run menu interface. */ -+ run_menu (menu_entries, config_entries, num_entries, -+ menu_entries + menu_len, default_entry); -+ } -+ } -+} -diff -Nur grub-0.97/stage2/term.h grub-0.97-patched/stage2/term.h ---- grub-0.97/stage2/term.h 2003-07-09 13:45:53.000000000 +0200 -+++ grub-0.97-patched/stage2/term.h 2012-11-11 17:06:33.311470556 +0100 -@@ -60,6 +60,8 @@ - const char *name; - /* The feature flags defined above. */ - unsigned long flags; -+ /* Default for maximum number of lines if not specified */ -+ unsigned short max_lines; - /* Put a character. */ - void (*putchar) (int c); - /* Check if any input character is available. */ -@@ -79,6 +81,11 @@ - void (*setcolor) (int normal_color, int highlight_color); - /* Turn on/off the cursor. */ - int (*setcursor) (int on); -+ -+ /* function to start a terminal */ -+ int (*startup) (void); -+ /* function to use to shutdown a terminal */ -+ void (*shutdown) (void); - }; - - /* This lists up available terminals. */ -@@ -124,4 +131,23 @@ - int hercules_setcursor (int on); - #endif - -+#ifdef SUPPORT_GRAPHICS -+extern int foreground, background, border, graphics_inited; -+ -+void graphics_set_splash(char *splashfile); -+int set_videomode (int mode); -+void graphics_putchar (int c); -+int graphics_getxy(void); -+void graphics_gotoxy(int x, int y); -+void graphics_cls(void); -+void graphics_setcolorstate (color_state state); -+void graphics_setcolor (int normal_color, int highlight_color); -+void graphics_setcursor (int on); -+int graphics_init(void); -+void graphics_end(void); -+ -+int hex(int v); -+void graphics_set_palette(int idx, int red, int green, int blue); -+#endif /* SUPPORT_GRAPHICS */ -+ - #endif /* ! GRUB_TERM_HEADER */ -diff -Nur grub-0.97/THANKS grub-0.97-patched/THANKS ---- grub-0.97/THANKS 2005-05-08 04:17:43.000000000 +0200 -+++ grub-0.97-patched/THANKS 2012-11-11 17:07:12.709729021 +0100 -@@ -121,3 +121,4 @@ - Yedidyah Bar-David didi@post.tau.ac.il - Yury V. Umanets umka@namesys.com - Yuri Zaporogets yuriz@ukr.net -+Vitaly Fertman vitaly@namesys.com -diff -Nur grub-0.97/util/grub-install.in grub-0.97-patched/util/grub-install.in ---- grub-0.97/util/grub-install.in 2004-07-24 20:57:31.000000000 +0200 -+++ grub-0.97-patched/util/grub-install.in 2012-11-11 17:07:12.748730268 +0100 -@@ -96,24 +96,27 @@ - # Break the device name into the disk part and the partition part. - case "$host_os" in - linux*) -- tmp_disk=`echo "$1" | sed -e 's%([sh]d[a-z])[0-9]*$%\1%' \ -+ tmp_disk=`echo "$1" | sed -e 's%([shv]d[a-z])[0-9]*$%\1%' \ - -e 's%(d[0-9]*)p[0-9]*$%\1%' \ - -e 's%(fd[0-9]*)$%\1%' \ - -e 's%/part[0-9]*$%/disc%' \ -- -e 's%(c[0-7]d[0-9]*).*$%\1%'` -- tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]([0-9]*)$%\1%' \ -+ -e 's%(c[0-7]d[0-9]*).*$%\1%' \ -+ -e 's%(e[0-9].[0-9]*).*$%\1%'` -+ tmp_part=`echo "$1" | sed -e 's%.*/[shv]d[a-z]([0-9]*)$%\1%' \ - -e 's%.*d[0-9]*p%%' \ - -e 's%.*/fd[0-9]*$%%' \ - -e 's%.*/floppy/[0-9]*$%%' \ - -e 's%.*/(disc|part([0-9]*))$%\2%' \ -- -e 's%.*c[0-7]d[0-9]*p%%'` -+ -e 's%.*c[0-7]d[0-9]*p*%%' \ -+ -e 's%.*e[0-9].[0-9]*p%%' \ -+ -e 's%.*e[0-9].[0-9]*$%%'` - ;; - gnu*) - tmp_disk=`echo "$1" | sed 's%([sh]d[0-9]*).*%\1%'` - tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;; - freebsd* | kfreebsd*-gnu) -- tmp_disk=`echo "$1" | sed 's%r{0,1}([saw]d[0-9]*).*$%r\1%' \ -- | sed 's%r{0,1}(da[0-9]*).*$%r\1%'` -+ tmp_disk=`echo "$1" | sed 's%r{0,1}([saw]d[0-9]*).*$%\1%' \ -+ | sed 's%r{0,1}(da[0-9]*).*$%\1%'` - tmp_part=`echo "$1" \ - | sed "s%.*/r{0,1}[saw]d[0-9](s[0-9]*[a-h])%\1%" \ - | sed "s%.*/r{0,1}da[0-9](s[0-9]*[a-h])%\1%"` -@@ -131,7 +134,7 @@ - - # Get the drive name. - tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \ -- | sed 's%.*(([hf]d[0-9][a-g0-9,]*)).*%\1%'` -+ | sed 's%.*(([hf]d[0-9][a-z0-9,]*)).*%\1%'` - - # If not found, print an error message and exit. - if test "x$tmp_drive" = x; then -@@ -148,13 +151,13 @@ - gnu*) - if echo $tmp_part | grep "^s" >/dev/null; then - tmp_pc_slice=`echo $tmp_part \ -- | sed "s%s([0-9]*)[a-g]*$%\1%"` -+ | sed "s%s([0-9]*)[a-z]*$%\1%"` - tmp_drive=`echo "$tmp_drive" \ - | sed "s%)%,`expr "$tmp_pc_slice" - 1`)%"` - fi -- if echo $tmp_part | grep "[a-g]$" >/dev/null; then -+ if echo $tmp_part | grep "[a-z]$" >/dev/null; then - tmp_bsd_partition=`echo "$tmp_part" \ -- | sed "s%[^a-g]*([a-g])$%\1%"` -+ | sed "s%[^a-z]*([a-z])$%\1%"` - tmp_drive=`echo "$tmp_drive" \ - | sed "s%)%,$tmp_bsd_partition)%"` - fi -@@ -336,6 +339,10 @@ - # Create a safe temporary file. - test -n "$mklog" && log_file=`$mklog` - -+ # Before all invocations of the grub shell, call sync to make sure -+ # the raw device is in sync with any bufferring in filesystems. -+ sync -+ - $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file - quit - EOF -@@ -450,6 +457,10 @@ - # Create a safe temporary file. - test -n "$mklog" && log_file=`$mklog` - -+# Before all invocations of the grub shell, call sync to make sure -+# the raw device is in sync with any bufferring in filesystems. -+sync -+ - # Now perform the installation. - $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file - root $root_drive -diff -Nur grub-0.97/util/grub-install.in.orig grub-0.97-patched/util/grub-install.in.orig ---- grub-0.97/util/grub-install.in.orig 1970-01-01 01:00:00.000000000 +0100 -+++ grub-0.97-patched/util/grub-install.in.orig 2004-07-24 20:57:31.000000000 +0200 -@@ -0,0 +1,477 @@ -+#! /bin/sh -+ -+# Install GRUB on your drive. -+# Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. -+# -+# This file 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, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ -+# Initialize some variables. -+prefix=@prefix@ -+exec_prefix=@exec_prefix@ -+sbindir=@sbindir@ -+libdir=@libdir@ -+PACKAGE=@PACKAGE@ -+VERSION=@VERSION@ -+host_cpu=@host_cpu@ -+host_os=@host_os@ -+host_vendor=@host_vendor@ -+pkglibdir=${libdir}/${PACKAGE}/${host_cpu}-${host_vendor} -+ -+grub_shell=${sbindir}/grub -+grub_set_default=${sbindir}/grub-set-default -+log_file=/tmp/grub-install.log.$$ -+img_file=/tmp/grub-install.img.$$ -+rootdir= -+grub_prefix=/boot/grub -+ -+install_device= -+no_floppy= -+force_lba= -+recheck=no -+debug=no -+ -+# look for secure tempfile creation wrappers on this platform -+if test -x /bin/tempfile; then -+ mklog="/bin/tempfile --prefix=grub" -+ mkimg="/bin/tempfile --prefix=grub" -+elif test -x /bin/mktemp; then -+ mklog="/bin/mktemp /tmp/grub-install.log.XXXXXX" -+ mkimg="/bin/mktemp /tmp/grub-install.img.XXXXXX" -+else -+ mklog="" -+ mkimg="" -+fi -+ -+# Usage: usage -+# Print the usage. -+usage () { -+ cat <<EOF -+Usage: grub-install [OPTION] install_device -+Install GRUB on your drive. -+ -+ -h, --help print this message and exit -+ -v, --version print the version information and exit -+ --root-directory=DIR install GRUB images under the directory DIR -+ instead of the root directory -+ --grub-shell=FILE use FILE as the grub shell -+ --no-floppy do not probe any floppy drive -+ --force-lba force GRUB to use LBA mode even for a buggy -+ BIOS -+ --recheck probe a device map even if it already exists -+ -+INSTALL_DEVICE can be a GRUB device name or a system device filename. -+ -+grub-install copies GRUB images into the DIR/boot directory specfied by -+--root-directory, and uses the grub shell to install grub into the boot -+sector. -+ -+Report bugs to bug-grub@gnu.org. -+EOF -+} -+ -+# Usage: convert os_device -+# Convert an OS device to the corresponding GRUB drive. -+# This part is OS-specific. -+convert () { -+ # First, check if the device file exists. -+ if test -e "$1"; then -+ : -+ else -+ echo "$1: Not found or not a block device." 1>&2 -+ exit 1 -+ fi -+ -+ # Break the device name into the disk part and the partition part. -+ case "$host_os" in -+ linux*) -+ tmp_disk=`echo "$1" | sed -e 's%([sh]d[a-z])[0-9]*$%\1%' \ -+ -e 's%(d[0-9]*)p[0-9]*$%\1%' \ -+ -e 's%(fd[0-9]*)$%\1%' \ -+ -e 's%/part[0-9]*$%/disc%' \ -+ -e 's%(c[0-7]d[0-9]*).*$%\1%'` -+ tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]([0-9]*)$%\1%' \ -+ -e 's%.*d[0-9]*p%%' \ -+ -e 's%.*/fd[0-9]*$%%' \ -+ -e 's%.*/floppy/[0-9]*$%%' \ -+ -e 's%.*/(disc|part([0-9]*))$%\2%' \ -+ -e 's%.*c[0-7]d[0-9]*p%%'` -+ ;; -+ gnu*) -+ tmp_disk=`echo "$1" | sed 's%([sh]d[0-9]*).*%\1%'` -+ tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;; -+ freebsd* | kfreebsd*-gnu) -+ tmp_disk=`echo "$1" | sed 's%r{0,1}([saw]d[0-9]*).*$%r\1%' \ -+ | sed 's%r{0,1}(da[0-9]*).*$%r\1%'` -+ tmp_part=`echo "$1" \ -+ | sed "s%.*/r{0,1}[saw]d[0-9](s[0-9]*[a-h])%\1%" \ -+ | sed "s%.*/r{0,1}da[0-9](s[0-9]*[a-h])%\1%"` -+ ;; -+ netbsd* | knetbsd*-gnu) -+ tmp_disk=`echo "$1" | sed 's%r{0,1}([sw]d[0-9]*).*$%r\1d%' \ -+ | sed 's%r{0,1}(fd[0-9]*).*$%r\1a%'` -+ tmp_part=`echo "$1" \ -+ | sed "s%.*/r{0,1}[sw]d[0-9]([abe-p])%\1%"` -+ ;; -+ *) -+ echo "grub-install does not support your OS yet." 1>&2 -+ exit 1 ;; -+ esac -+ -+ # Get the drive name. -+ tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \ -+ | sed 's%.*(([hf]d[0-9][a-g0-9,]*)).*%\1%'` -+ -+ # If not found, print an error message and exit. -+ if test "x$tmp_drive" = x; then -+ echo "$1 does not have any corresponding BIOS drive." 1>&2 -+ exit 1 -+ fi -+ -+ if test "x$tmp_part" != x; then -+ # If a partition is specified, we need to translate it into the -+ # GRUB's syntax. -+ case "$host_os" in -+ linux*) -+ echo "$tmp_drive" | sed "s%)$%,`expr $tmp_part - 1`)%" ;; -+ gnu*) -+ if echo $tmp_part | grep "^s" >/dev/null; then -+ tmp_pc_slice=`echo $tmp_part \ -+ | sed "s%s([0-9]*)[a-g]*$%\1%"` -+ tmp_drive=`echo "$tmp_drive" \ -+ | sed "s%)%,`expr "$tmp_pc_slice" - 1`)%"` -+ fi -+ if echo $tmp_part | grep "[a-g]$" >/dev/null; then -+ tmp_bsd_partition=`echo "$tmp_part" \ -+ | sed "s%[^a-g]*([a-g])$%\1%"` -+ tmp_drive=`echo "$tmp_drive" \ -+ | sed "s%)%,$tmp_bsd_partition)%"` -+ fi -+ echo "$tmp_drive" ;; -+ freebsd* | kfreebsd*-gnu) -+ if echo $tmp_part | grep "^s" >/dev/null; then -+ tmp_pc_slice=`echo $tmp_part \ -+ | sed "s%s([0-9]*)[a-h]*$%\1%"` -+ tmp_drive=`echo "$tmp_drive" \ -+ | sed "s%)%,`expr "$tmp_pc_slice" - 1`)%"` -+ fi -+ if echo $tmp_part | grep "[a-h]$" >/dev/null; then -+ tmp_bsd_partition=`echo "$tmp_part" \ -+ | sed "s%s{0,1}[0-9]*([a-h])$%\1%"` -+ tmp_drive=`echo "$tmp_drive" \ -+ | sed "s%)%,$tmp_bsd_partition)%"` -+ fi -+ echo "$tmp_drive" ;; -+ netbsd* | knetbsd*-gnu) -+ if echo $tmp_part | grep "^[abe-p]$" >/dev/null; then -+ tmp_bsd_partition=`echo "$tmp_part" \ -+ | sed "s%([a-p])$%\1%"` -+ tmp_drive=`echo "$tmp_drive" \ -+ | sed "s%)%,$tmp_bsd_partition)%"` -+ fi -+ echo "$tmp_drive" ;; -+ esac -+ else -+ # If no partition is specified, just print the drive name. -+ echo "$tmp_drive" -+ fi -+} -+ -+# Usage: resolve_symlink file -+# Find the real file/device that file points at -+resolve_symlink () { -+ tmp_fname=$1 -+ # Resolve symlinks -+ while test -L $tmp_fname; do -+ tmp_new_fname=`ls -al $tmp_fname | sed -n 's%.*-> (.*)%\1%p'` -+ if test -z "$tmp_new_fname"; then -+ echo "Unrecognized ls output" 2>&1 -+ exit 1 -+ fi -+ -+ # Convert relative symlinks -+ case $tmp_new_fname in -+ /*) tmp_fname="$tmp_new_fname" -+ ;; -+ *) tmp_fname="`echo $tmp_fname | sed 's%/[^/]*$%%'`/$tmp_new_fname" -+ ;; -+ esac -+ done -+ echo "$tmp_fname" -+} -+ -+# Usage: find_device file -+# Find block device on which the file resides. -+find_device () { -+ # For now, this uses the program `df' to get the device name, but is -+ # this really portable? -+ tmp_fname=`df $1/ | sed -n 's%.*(/dev/[^ ]*).*%\1%p'` -+ -+ if test -z "$tmp_fname"; then -+ echo "Could not find device for $1" 2>&1 -+ exit 1 -+ fi -+ -+ tmp_fname=`resolve_symlink $tmp_fname` -+ -+ echo "$tmp_fname" -+} -+ -+# Check the arguments. -+for option in "$@"; do -+ case "$option" in -+ -h | --help) -+ usage -+ exit 0 ;; -+ -v | --version) -+ echo "grub-install (GNU GRUB ${VERSION})" -+ exit 0 ;; -+ --root-directory=*) -+ rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; -+ --grub-shell=*) -+ grub_shell=`echo "$option" | sed 's/--grub-shell=//'` ;; -+ --no-floppy) -+ no_floppy="--no-floppy" ;; -+ --force-lba) -+ force_lba="--force-lba" ;; -+ --recheck) -+ recheck=yes ;; -+ # This is an undocumented feature... -+ --debug) -+ debug=yes ;; -+ -*) -+ echo "Unrecognized option `$option'" 1>&2 -+ usage -+ exit 1 -+ ;; -+ *) -+ if test "x$install_device" != x; then -+ echo "More than one install_devices?" 1>&2 -+ usage -+ exit 1 -+ fi -+ install_device="${option}" ;; -+ esac -+done -+ -+if test "x$install_device" = x; then -+ echo "install_device not specified." 1>&2 -+ usage -+ exit 1 -+fi -+ -+# If the debugging feature is enabled, print commands. -+if test $debug = yes; then -+ set -x -+fi -+ -+# Initialize these directories here, since ROOTDIR was initialized. -+case "$host_os" in -+netbsd* | openbsd*) -+ # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub -+ # instead of /boot/grub. -+ grub_prefix=/grub -+ bootdir=${rootdir} -+ ;; -+*) -+ # Use /boot/grub by default. -+ bootdir=${rootdir}/boot -+ ;; -+esac -+ -+grubdir=${bootdir}/grub -+device_map=${grubdir}/device.map -+ -+# Check if GRUB is installed. -+# This is necessary, because the user can specify "grub --read-only". -+set $grub_shell dummy -+if test -f "$1"; then -+ : -+else -+ echo "$1: Not found." 1>&2 -+ exit 1 -+fi -+ -+if test -f "$pkglibdir/stage1"; then -+ : -+else -+ echo "${pkglibdir}/stage1: Not found." 1>&2 -+ exit 1 -+fi -+ -+if test -f "$pkglibdir/stage2"; then -+ : -+else -+ echo "${pkglibdir}/stage2: Not found." 1>&2 -+ exit 1 -+fi -+ -+# Don't check for *stage1_5, because it is not fatal even if any -+# Stage 1.5 does not exist. -+ -+# Create the GRUB directory if it is not present. -+test -d "$bootdir" || mkdir "$bootdir" || exit 1 -+test -d "$grubdir" || mkdir "$grubdir" || exit 1 -+ -+# If --recheck is specified, remove the device map, if present. -+if test $recheck = yes; then -+ rm -f $device_map -+fi -+ -+# Create the device map file if it is not present. -+if test -f "$device_map"; then -+ : -+else -+ # Create a safe temporary file. -+ test -n "$mklog" && log_file=`$mklog` -+ -+ $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file -+quit -+EOF -+ if grep "Error [0-9]*: " $log_file >/dev/null; then -+ cat $log_file 1>&2 -+ exit 1 -+ fi -+ -+ rm -f $log_file -+fi -+ -+# Make sure that there is no duplicated entry. -+tmp=`sed -n '/^([fh]d[0-9]*)/s/(^(.*)).*/\1/p' $device_map \ -+ | sort | uniq -d | sed -n 1p` -+if test -n "$tmp"; then -+ echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2 -+ exit 1 -+fi -+ -+# Check for INSTALL_DEVICE. -+case "$install_device" in -+/dev/*) -+ install_device=`resolve_symlink "$install_device"` -+ install_drive=`convert "$install_device"` -+ # I don't know why, but some shells wouldn't die if exit is -+ # called in a function. -+ if test "x$install_drive" = x; then -+ exit 1 -+ fi ;; -+([hf]d[0-9]*)) -+ install_drive="$install_device" ;; -+[hf]d[0-9]*) -+ # The GRUB format with no parenthesis. -+ install_drive="($install_device)" ;; -+*) -+ echo "Format of install_device not recognized." 1>&2 -+ usage -+ exit 1 ;; -+esac -+ -+# Get the root drive. -+root_device=`find_device ${rootdir}` -+bootdir_device=`find_device ${bootdir}` -+ -+# Check if the boot directory is in the same device as the root directory. -+if test "x$root_device" != "x$bootdir_device"; then -+ # Perhaps the user has a separate boot partition. -+ root_device=$bootdir_device -+ grub_prefix="/grub" -+fi -+ -+# Convert the root device to a GRUB drive. -+root_drive=`convert "$root_device"` -+if test "x$root_drive" = x; then -+ exit 1 -+fi -+ -+# Check if the root directory exists in the same device as the grub -+# directory. -+grubdir_device=`find_device ${grubdir}` -+ -+if test "x$grubdir_device" != "x$root_device"; then -+ # For now, cannot deal with this situation. -+ cat <<EOF 1>&2 -+You must set the root directory by the option --root-directory, because -+$grubdir does not exist in the root device $root_device. -+EOF -+ exit 1 -+fi -+ -+# Copy the GRUB images to the GRUB directory. -+for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do -+ rm -f $file || exit 1 -+done -+for file in \ -+ ${pkglibdir}/stage1 ${pkglibdir}/stage2 ${pkglibdir}/*stage1_5; do -+ cp -f $file ${grubdir} || exit 1 -+done -+ -+# Make a default file. -+${grub_set_default} --root-directory=${rootdir} default -+ -+# Make sure that GRUB reads the same images as the host OS. -+test -n "$mkimg" && img_file=`$mkimg` -+test -n "$mklog" && log_file=`$mklog` -+ -+for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do -+ count=5 -+ tmp=`echo $file | sed "s|^${grubdir}|${grub_prefix}|"` -+ while test $count -gt 0; do -+ $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file -+dump ${root_drive}${tmp} ${img_file} -+quit -+EOF -+ if grep "Error [0-9]*: " $log_file >/dev/null; then -+ : -+ elif cmp $file $img_file >/dev/null; then -+ break -+ fi -+ sleep 1 -+ count=`expr $count - 1` -+ done -+ if test $count -eq 0; then -+ echo "The file $file not read correctly." 1>&2 -+ exit 1 -+ fi -+done -+ -+rm -f $img_file -+rm -f $log_file -+ -+# Create a safe temporary file. -+test -n "$mklog" && log_file=`$mklog` -+ -+# Now perform the installation. -+$grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file -+root $root_drive -+setup $force_lba --stage2=$grubdir/stage2 --prefix=$grub_prefix $install_drive -+quit -+EOF -+ -+if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then -+ cat $log_file 1>&2 -+ exit 1 -+fi -+ -+rm -f $log_file -+ -+# Prompt the user to check if the device map is correct. -+echo "Installation finished. No error reported." -+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 "fix it and re-run the script `grub-install'." -+echo -+ -+cat $device_map -+ -+# Bye. -+exit 0 -diff -Nur grub-0.97/util/mkbimage grub-0.97-patched/util/mkbimage ---- grub-0.97/util/mkbimage 2004-07-24 20:57:31.000000000 +0200 -+++ grub-0.97-patched/util/mkbimage 2012-11-11 17:07:12.744730138 +0100 -@@ -1,7 +1,7 @@ - #!/bin/sh - # MaKe a Bootable IMAGE --- 1.44, 2.88 and El Torito no-emulation mode - # C) 2001,2002,2003 Thierry Laronde tlaronde@polynum.org --# C) 2001,2002,2003 Robert Millan robertmh@gnu.org -+# C) 2001,2002,2003 Robert Millan rmh@aybabtu.com - - - # This program is free software; you can redistribute it and/or modify -@@ -94,15 +94,13 @@ - display Version information and exit - - Copyright (c) 2001,2002,2003 Thierry Laronde tlaronde@polynum.org. --Copyright (c) 2001,2002 Robert Millan zeratul2@wanadoo.es. - GPLed." - - version="mkbimage $version_number - --Written by Thierry Laronde and Robert Millan. -+Written by Thierry Laronde. - - Copyright (c) 2001,2002,2003 Thierry Laronde tlaronde@polynum.org. --Copyright (c) 2001,2002,2003 Robert Millan zeratul2@wanadoo.es. - - This is free software under the GPL version 2 or later; see the source for - copying conditions. There is NO warranty, not even for MERCHANTABILITY or diff --git a/src/patches/lcd4linux-scaletext-dpf.patch b/src/patches/lcd4linux-scaletext-dpf.patch deleted file mode 100644 index c075dc7..0000000 --- a/src/patches/lcd4linux-scaletext-dpf.patch +++ /dev/null @@ -1,59 +0,0 @@ -diff -rupN --exclude=.svn --exclude='*.log' --exclude=Makefile --exclude='*.m4' --exclude='*.in' --exclude=autom4te.cache --exclude='config*' --exclude='*.Po' --exclude='*.sh' lcd4linux/drv_dpf.c lcd4linux.1/drv_dpf.c ---- lcd4linux/drv_dpf.c 2011-11-14 14:41:40.859787820 +0100 -+++ lcd4linux.1/drv_dpf.c 2011-11-13 14:42:58.650315817 +0100 -@@ -160,12 +160,26 @@ static int drv_dpf_start2(const char *se - } - - /* Fixme: provider other fonts someday... */ -- if (XRES != 6 && YRES != 8) { -+ /* Overridden - we have scaled the textout drawing */ -+/* if (XRES != 6 && YRES != 8) { - error("%s: bad Font '%s' from %s (only 6x8 at the moment)", - Name, s, cfg_source()); - return -1; -+ } */ -+ -+ /* we dont want fonts below 6 width */ -+ if (XRES <6) { -+ error("%s: bad Font '%s' width '%d' using minimum of 6)", -+ Name,s,XRES); -+ XRES = 6; - } - -+ /* we dont want fonts below 8 height */ -+ if (YRES <8) { -+ error("%s: bad Font '%s' height '%d' using minimum of 8)", -+ Name,s,YRES); -+ YRES = 8; -+ } - - /* open communication with the display */ - if (drv_dpf_open(section) < 0) { -diff -rupN --exclude=.svn --exclude='*.log' --exclude=Makefile --exclude='*.m4' --exclude='*.in' --exclude=autom4te.cache --exclude='config*' --exclude='*.Po' --exclude='*.sh' lcd4linux/drv_generic_graphic.c lcd4linux.1/drv_generic_graphic.c ---- lcd4linux/drv_generic_graphic.c 2011-11-14 14:41:40.614375417 +0100 -+++ lcd4linux.1/drv_generic_graphic.c 2011-11-14 14:58:29.303285793 +0100 -@@ -259,15 +259,18 @@ static void drv_generic_graphic_render(c - } - - for (y = 0; y < YRES; y++) { -- int mask = 1 << XRES; -+ - for (x = 0; x < XRES; x++) { -- mask >>= 1; -- if (chr[y] & mask) -- drv_generic_graphic_FB[layer][(r + y) * LCOLS + c + x] = fg; -- else -- drv_generic_graphic_FB[layer][(r + y) * LCOLS + c + x] = bg; -+ int mask = 1 << 6; -+ mask >>= ((x*6)/(XRES))+1; -+ if (chr[(y*8)/(YRES)] & mask) -+ drv_generic_graphic_FB[layer][(r + y ) * LCOLS + c + x] = fg; -+ else -+ drv_generic_graphic_FB[layer][(r + y ) * LCOLS + c + x] = bg; -+ - } - } -+ - c += XRES; - txt++; - } diff --git a/src/patches/libcap-1.10-shared.patch b/src/patches/libcap-1.10-shared.patch deleted file mode 100644 index 9272c37..0000000 --- a/src/patches/libcap-1.10-shared.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -ruN libcap-1.10.old/libcap/Makefile libcap-1.10/libcap/Makefile ---- libcap-1.10.old/libcap/Makefile 1999-04-18 00:16:31.000000000 +0200 -+++ libcap-1.10/libcap/Makefile 2004-01-14 10:47:20.000000000 +0100 -@@ -56,12 +56,12 @@ - # @sed -ne '/^#define[ \t]CAP[_A-Z]+[ \t]+[0-9]+/{s/^#define CAP_([^ \t]*)[ \t]*([^ \t]*)/ { \2, "\1" },/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' < /usr/include/linux/capability.h | fgrep -v 0x > cap_names.sed - - $(MINLIBNAME): $(OBJS) -- $(LD) -soname $(MAJLIBNAME) -x -shared -o $@ $(OBJS) -+ $(CC) -Wl,-soname,$(MAJLIBNAME) -Wl,-x -shared -o $@ $(OBJS) - ln -sf $(MINLIBNAME) $(MAJLIBNAME) - ln -sf $(MAJLIBNAME) $(LIBNAME) - - %.o: %.c $(INCLS) -- $(CC) $(CFLAGS) -c $< -o $@ -+ $(CC) $(CFLAGS) -fpic -c $< -o $@ - - install: all - mkdir -p -m 0755 $(INCDIR)/sys diff --git a/src/patches/libcap-1.10-syscall.patch b/src/patches/libcap-1.10-syscall.patch deleted file mode 100644 index 6053185..0000000 --- a/src/patches/libcap-1.10-syscall.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- libcap-1.10.old/libcap/cap_sys.c 2003-08-24 19:03:35.524759616 -0700 -+++ libcap-1.10/libcap/cap_sys.c 2003-08-24 19:03:48.406801248 -0700 -@@ -10,7 +10,7 @@ - #include "libcap.h" - #define __LIBRARY__ - #include <linux/unistd.h> -- -+/* - _syscall2(int, capget, - cap_user_header_t, header, - cap_user_data_t, data) -@@ -18,7 +18,7 @@ - _syscall2(int, capset, - cap_user_header_t, header, - const cap_user_data_t, data) -- -+*/ - /* - * $Log: libcap-1.10-syscall.patch,v $ - * Revision 1.1 2004/01/14 13:11:39 riddles - * Build shared libcap - * - * Revision 1.2 2003/08/29 06:28:38 cretin - * Only add -fPIC for libcap.so objects - * - * Revision 1.1 2003/08/27 06:10:53 cretin - * Added -fPIC for prelink to work, and fixed compile error - * - * Revision 1.1.1.1 1999/04/17 22:16:31 morgan ---- libcap-1.10.old/Make.Rules Mon May 21 16:22:08 2001 -+++ libcap-1.10/Make.Rules Mon May 21 16:22:32 2001 -@@ -44,10 +44,10 @@ - CC=gcc - COPTFLAGS=-O2 - DEBUG=-g #-DDEBUG --WARNINGS=-ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \ -+WARNINGS=-D_POSIX_SOURCE -Wall -Wwrite-strings \ - -Wpointer-arith -Wcast-qual -Wcast-align \ - -Wtraditional -Wstrict-prototypes -Wmissing-prototypes \ -- -Wnested-externs -Winline -Wshadow -pedantic -+ -Wnested-externs -Winline -Wshadow - LD=ld - LDFLAGS=-s #-g diff --git a/src/patches/libnl-1.1-ULONG_MAX.patch b/src/patches/libnl-1.1-ULONG_MAX.patch deleted file mode 100644 index ca3dd40..0000000 --- a/src/patches/libnl-1.1-ULONG_MAX.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- libnl-1.1/include/netlink-local.h.orig 2008-06-08 19:09:20.000000000 +0200 -+++ libnl-1.1/include/netlink-local.h 2008-06-08 19:09:33.000000000 +0200 -@@ -26,6 +26,7 @@ - #include <sys/socket.h> - #include <inttypes.h> - #include <assert.h> -+#include <limits.h> - - #include <arpa/inet.h> - #include <netdb.h> - diff --git a/src/patches/libsigc++-gcc43.patch b/src/patches/libsigc++-gcc43.patch deleted file mode 100644 index 528f21e..0000000 --- a/src/patches/libsigc++-gcc43.patch +++ /dev/null @@ -1,85 +0,0 @@ -diff -urN libsigc++-2.0-2.0.17.old/sigc++/signal.h libsigc++-2.0-2.0.17/sigc++/signal.h ---- libsigc++-2.0-2.0.17.old/sigc++/signal.h 2005-12-20 08:35:21.000000000 +0000 -+++ libsigc++-2.0-2.0.17/sigc++/signal.h 2008-02-22 00:22:44.000000000 +0000 -@@ -1661,7 +1661,7 @@ - typedef internal::signal_emit0<T_return, T_accumulator> emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot<T_return> slot_type; -- typedef slot_list<slot_type> slot_list_type; -+ typedef sigc::slot_list<slot_type> slot_list_type; - typedef typename slot_list_type::iterator iterator; - typedef typename slot_list_type::const_iterator const_iterator; - typedef typename slot_list_type::reverse_iterator reverse_iterator; -@@ -1770,7 +1770,7 @@ - typedef internal::signal_emit1<T_return, T_arg1, T_accumulator> emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot<T_return, T_arg1> slot_type; -- typedef slot_list<slot_type> slot_list_type; -+ typedef sigc::slot_list<slot_type> slot_list_type; - typedef typename slot_list_type::iterator iterator; - typedef typename slot_list_type::const_iterator const_iterator; - typedef typename slot_list_type::reverse_iterator reverse_iterator; -@@ -1881,7 +1881,7 @@ - typedef internal::signal_emit2<T_return, T_arg1,T_arg2, T_accumulator> emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot<T_return, T_arg1,T_arg2> slot_type; -- typedef slot_list<slot_type> slot_list_type; -+ typedef sigc::slot_list<slot_type> slot_list_type; - typedef typename slot_list_type::iterator iterator; - typedef typename slot_list_type::const_iterator const_iterator; - typedef typename slot_list_type::reverse_iterator reverse_iterator; -@@ -1994,7 +1994,7 @@ - typedef internal::signal_emit3<T_return, T_arg1,T_arg2,T_arg3, T_accumulator> emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot<T_return, T_arg1,T_arg2,T_arg3> slot_type; -- typedef slot_list<slot_type> slot_list_type; -+ typedef sigc::slot_list<slot_type> slot_list_type; - typedef typename slot_list_type::iterator iterator; - typedef typename slot_list_type::const_iterator const_iterator; - typedef typename slot_list_type::reverse_iterator reverse_iterator; -@@ -2109,7 +2109,7 @@ - typedef internal::signal_emit4<T_return, T_arg1,T_arg2,T_arg3,T_arg4, T_accumulator> emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot<T_return, T_arg1,T_arg2,T_arg3,T_arg4> slot_type; -- typedef slot_list<slot_type> slot_list_type; -+ typedef sigc::slot_list<slot_type> slot_list_type; - typedef typename slot_list_type::iterator iterator; - typedef typename slot_list_type::const_iterator const_iterator; - typedef typename slot_list_type::reverse_iterator reverse_iterator; -@@ -2226,7 +2226,7 @@ - typedef internal::signal_emit5<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5, T_accumulator> emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5> slot_type; -- typedef slot_list<slot_type> slot_list_type; -+ typedef sigc::slot_list<slot_type> slot_list_type; - typedef typename slot_list_type::iterator iterator; - typedef typename slot_list_type::const_iterator const_iterator; - typedef typename slot_list_type::reverse_iterator reverse_iterator; -@@ -2345,7 +2345,7 @@ - typedef internal::signal_emit6<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6, T_accumulator> emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6> slot_type; -- typedef slot_list<slot_type> slot_list_type; -+ typedef sigc::slot_list<slot_type> slot_list_type; - typedef typename slot_list_type::iterator iterator; - typedef typename slot_list_type::const_iterator const_iterator; - typedef typename slot_list_type::reverse_iterator reverse_iterator; -@@ -2466,7 +2466,7 @@ - typedef internal::signal_emit7<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6,T_arg7, T_accumulator> emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6,T_arg7> slot_type; -- typedef slot_list<slot_type> slot_list_type; -+ typedef sigc::slot_list<slot_type> slot_list_type; - typedef typename slot_list_type::iterator iterator; - typedef typename slot_list_type::const_iterator const_iterator; - typedef typename slot_list_type::reverse_iterator reverse_iterator; -diff -urN libsigc++-2.0-2.0.17.old/tests/test_copy_invalid_slot.cc libsigc++-2.0-2.0.17/tests/test_copy_invalid_slot.cc ---- libsigc++-2.0-2.0.17.old/tests/test_copy_invalid_slot.cc 2005-05-01 02:00:47.000000000 +0000 -+++ libsigc++-2.0-2.0.17/tests/test_copy_invalid_slot.cc 2008-02-22 00:24:08.000000000 +0000 -@@ -1,4 +1,6 @@ - #include <iostream> -+#include <cstdlib> -+#include <cstring> - #include <sigc++/sigc++.h> - - void Foo(sigc::trackable &t) {} diff --git a/src/patches/lzo-2.06-CVE-2014-4607.patch b/src/patches/lzo-2.06-CVE-2014-4607.patch old mode 100755 new mode 100644 diff --git a/src/patches/nasm-0.98.39-security_fix-1.patch b/src/patches/nasm-0.98.39-security_fix-1.patch deleted file mode 100644 index 795d0a3..0000000 --- a/src/patches/nasm-0.98.39-security_fix-1.patch +++ /dev/null @@ -1,21 +0,0 @@ -Submitted By: Ken Moffat ken@kenmoffat.uklinux.net -Date: 2005-08-08 -Initial Package Version: 0.98.39 -Upstream Status: From upstream cvs -Origin: Extracted by Ken Moffat -Description: This is Jindrich Novy's patch to fix another buffer overrun -in nasm, CAN-2005-1194 (users who can be persuaded to assemble and run a -malicious source file can have arbitrary code executed via a buffer -overflow). - ---- nasm-0.98.39/output/outieee.c.orig 2005-01-15 22:16:08.000000000 +0000 -+++ nasm-0.98.39/output/outieee.c 2005-08-08 22:12:46.000000000 +0100 -@@ -1120,7 +1120,7 @@ - va_list ap; - - va_start(ap, format); -- vsprintf(buffer, format, ap); -+ vsnprintf(buffer, sizeof(buffer), format, ap); - l = strlen(buffer); - for (i = 0; i < l; i++) - if ((buffer[i] & 0xff) > 31) diff --git a/src/patches/net-tools-1.60-kernel_headers-2.patch b/src/patches/net-tools-1.60-kernel_headers-2.patch deleted file mode 100644 index c881537..0000000 --- a/src/patches/net-tools-1.60-kernel_headers-2.patch +++ /dev/null @@ -1,51 +0,0 @@ -Submitted By: Jim Gifford (jim at linuxfromscratch dot org) -Date: 2004-06-24 -Initial Package Version: 2.6 -Origin: Gentoo and Self -Upstream Status: N/A -Description: Fixes Compile Issues with the 2.6 Kernel - - -diff -Naur net-tools-1.60.orig/hostname.c net-tools-1.60/hostname.c ---- net-tools-1.60.orig/hostname.c 2001-04-08 17:04:23.000000000 +0000 -+++ net-tools-1.60/hostname.c 2004-06-24 06:17:32.517305695 +0000 -@@ -42,10 +42,16 @@ - #include "config.h" - #include "version.h" - #include "../intl.h" -+#include <linux/version.h> - - #if HAVE_AFDECnet -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - #include <netdnet/dn.h> - #endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -+#include <linux/dn.h> -+#endif -+#endif - - char *Release = RELEASE, *Version = "hostname 1.100 (2001-04-14)"; - -diff -Naur net-tools-1.60.orig/lib/x25_sr.c net-tools-1.60/lib/x25_sr.c ---- net-tools-1.60.orig/lib/x25_sr.c 2000-05-20 13:38:10.000000000 +0000 -+++ net-tools-1.60/lib/x25_sr.c 2004-06-24 06:15:45.163773724 +0000 -@@ -22,6 +22,7 @@ - #include <sys/socket.h> - #include <sys/ioctl.h> - #include <linux/x25.h> -+#include <linux/version.h> - #include <ctype.h> - #include <errno.h> - #include <netdb.h> -@@ -77,7 +78,11 @@ - rt.sigdigits=sigdigits; - - /* x25_route_struct.address isn't type struct sockaddr_x25, Why? */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) - memcpy(&rt.address, &sx25.sx25_addr, sizeof(x25_address)); -+#else -+ memcpy(&rt.address, &sx25.sx25_addr, sizeof(struct x25_address)); -+#endif - - while (*args) { - if (!strcmp(*args,"device") || !strcmp(*args,"dev")) { diff --git a/src/patches/netfilter_layer7_2.22_kernel3.0.patch b/src/patches/netfilter_layer7_2.22_kernel3.0.patch deleted file mode 100644 index 82d8509..0000000 --- a/src/patches/netfilter_layer7_2.22_kernel3.0.patch +++ /dev/null @@ -1,2160 +0,0 @@ -diff -Naur linux-3.0.24.org/include/linux/netfilter/xt_layer7.h linux-3.0.24/include/linux/netfilter/xt_layer7.h ---- linux-3.0.24.org/include/linux/netfilter/xt_layer7.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.0.24/include/linux/netfilter/xt_layer7.h 2012-03-15 20:08:48.976050501 +0100 -@@ -0,0 +1,13 @@ -+#ifndef _XT_LAYER7_H -+#define _XT_LAYER7_H -+ -+#define MAX_PATTERN_LEN 8192 -+#define MAX_PROTOCOL_LEN 256 -+ -+struct xt_layer7_info { -+ char protocol[MAX_PROTOCOL_LEN]; -+ char pattern[MAX_PATTERN_LEN]; -+ u_int8_t invert; -+}; -+ -+#endif /* _XT_LAYER7_H */ -diff -Naur linux-3.0.24.org/include/net/netfilter/nf_conntrack.h linux-3.0.24/include/net/netfilter/nf_conntrack.h ---- linux-3.0.24.org/include/net/netfilter/nf_conntrack.h 2012-03-12 18:58:19.000000000 +0100 -+++ linux-3.0.24/include/net/netfilter/nf_conntrack.h 2012-03-15 20:11:43.806042495 +0100 -@@ -134,6 +134,22 @@ - struct net *ct_net; - #endif - -+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || \ -+ defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) -+ struct { -+ /* -+ * e.g. "http". NULL before decision. "unknown" after decision -+ * if no match. -+ */ -+ char *app_proto; -+ /* -+ * application layer data so far. NULL after match decision. -+ */ -+ char *app_data; -+ unsigned int app_data_len; -+ } layer7; -+#endif -+ - /* Storage reserved for other modules, must be the last member */ - union nf_conntrack_proto proto; - }; -diff -Naur linux-3.0.24.org/net/netfilter/Kconfig linux-3.0.24/net/netfilter/Kconfig ---- linux-3.0.24.org/net/netfilter/Kconfig 2012-03-12 18:58:19.000000000 +0100 -+++ linux-3.0.24/net/netfilter/Kconfig 2012-03-15 20:46:12.046043918 +0100 -@@ -1020,6 +1020,26 @@ - - To compile it as a module, choose M here. If unsure, say N. - -+config NETFILTER_XT_MATCH_LAYER7 -+ tristate '"layer7" match support' -+ depends on NETFILTER_XTABLES -+ depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK) -+ help -+ Say Y if you want to be able to classify connections (and their -+ packets) based on regular expression matching of their application -+ layer data. This is one way to classify applications such as -+ peer-to-peer filesharing systems that do not always use the same -+ port. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_LAYER7_DEBUG -+ bool 'Layer 7 debugging output' -+ depends on NETFILTER_XT_MATCH_LAYER7 -+ help -+ Say Y to get lots of debugging output. -+ -+ - config NETFILTER_XT_MATCH_STATISTIC - tristate '"statistic" match support' - depends on NETFILTER_ADVANCED -diff -Naur linux-3.0.24.org/net/netfilter/Makefile linux-3.0.24/net/netfilter/Makefile ---- linux-3.0.24.org/net/netfilter/Makefile 2012-03-12 18:58:19.000000000 +0100 -+++ linux-3.0.24/net/netfilter/Makefile 2012-03-15 20:08:49.016044445 +0100 -@@ -102,6 +102,7 @@ - obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o - obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o - obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o -+obj-$(CONFIG_NETFILTER_XT_MATCH_LAYER7) += xt_layer7.o - obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o - obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o - obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o -diff -Naur linux-3.0.24.org/net/netfilter/nf_conntrack_core.c linux-3.0.24/net/netfilter/nf_conntrack_core.c ---- linux-3.0.24.org/net/netfilter/nf_conntrack_core.c 2012-03-12 18:58:19.000000000 +0100 -+++ linux-3.0.24/net/netfilter/nf_conntrack_core.c 2012-03-15 20:08:49.026044761 +0100 -@@ -213,6 +213,14 @@ - * too. */ - nf_ct_remove_expectations(ct); - -+ #if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) -+ if(ct->layer7.app_proto) -+ kfree(ct->layer7.app_proto); -+ if(ct->layer7.app_data) -+ kfree(ct->layer7.app_data); -+ #endif -+ -+ - /* We overload first tuple to link into unconfirmed list. */ - if (!nf_ct_is_confirmed(ct)) { - BUG_ON(hlist_nulls_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode)); -diff -Naur linux-3.0.24.org/net/netfilter/nf_conntrack_standalone.c linux-3.0.24/net/netfilter/nf_conntrack_standalone.c ---- linux-3.0.24.org/net/netfilter/nf_conntrack_standalone.c 2012-03-12 18:58:19.000000000 +0100 -+++ linux-3.0.24/net/netfilter/nf_conntrack_standalone.c 2012-03-15 20:08:49.036047262 +0100 -@@ -239,6 +239,12 @@ - if (ct_show_delta_time(s, ct)) - goto release; - -+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) -+ if(ct->layer7.app_proto && -+ seq_printf(s, "l7proto=%s ", ct->layer7.app_proto)) -+ return -ENOSPC; -+#endif -+ - if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use))) - goto release; - -diff -Naur linux-3.0.24.org/net/netfilter/regexp/regexp.c linux-3.0.24/net/netfilter/regexp/regexp.c ---- linux-3.0.24.org/net/netfilter/regexp/regexp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.0.24/net/netfilter/regexp/regexp.c 2012-03-15 20:08:49.066043520 +0100 -@@ -0,0 +1,1197 @@ -+/* -+ * regcomp and regexec -- regsub and regerror are elsewhere -+ * @(#)regexp.c 1.3 of 18 April 87 -+ * -+ * Copyright (c) 1986 by University of Toronto. -+ * Written by Henry Spencer. Not derived from licensed software. -+ * -+ * Permission is granted to anyone to use this software for any -+ * purpose on any computer system, and to redistribute it freely, -+ * subject to the following restrictions: -+ * -+ * 1. The author is not responsible for the consequences of use of -+ * this software, no matter how awful, even if they arise -+ * from defects in it. -+ * -+ * 2. The origin of this software must not be misrepresented, either -+ * by explicit claim or by omission. -+ * -+ * 3. Altered versions must be plainly marked as such, and must not -+ * be misrepresented as being the original software. -+ * -+ * Beware that some of this code is subtly aware of the way operator -+ * precedence is structured in regular expressions. Serious changes in -+ * regular-expression syntax might require a total rethink. -+ * -+ * This code was modified by Ethan Sommer to work within the kernel -+ * (it now uses kmalloc etc..) -+ * -+ * Modified slightly by Matthew Strait to use more modern C. -+ */ -+ -+#include "regexp.h" -+#include "regmagic.h" -+ -+/* added by ethan and matt. Lets it work in both kernel and user space. -+(So iptables can use it, for instance.) Yea, it goes both ways... */ -+#if __KERNEL__ -+ #define malloc(foo) kmalloc(foo,GFP_ATOMIC) -+#else -+ #define printk(format,args...) printf(format,##args) -+#endif -+ -+void regerror(char * s) -+{ -+ printk("<3>Regexp: %s\n", s); -+ /* NOTREACHED */ -+} -+ -+/* -+ * The "internal use only" fields in regexp.h are present to pass info from -+ * compile to execute that permits the execute phase to run lots faster on -+ * simple cases. They are: -+ * -+ * regstart char that must begin a match; '\0' if none obvious -+ * reganch is the match anchored (at beginning-of-line only)? -+ * regmust string (pointer into program) that match must include, or NULL -+ * regmlen length of regmust string -+ * -+ * Regstart and reganch permit very fast decisions on suitable starting points -+ * for a match, cutting down the work a lot. Regmust permits fast rejection -+ * of lines that cannot possibly match. The regmust tests are costly enough -+ * that regcomp() supplies a regmust only if the r.e. contains something -+ * potentially expensive (at present, the only such thing detected is * or + -+ * at the start of the r.e., which can involve a lot of backup). Regmlen is -+ * supplied because the test in regexec() needs it and regcomp() is computing -+ * it anyway. -+ */ -+ -+/* -+ * Structure for regexp "program". This is essentially a linear encoding -+ * of a nondeterministic finite-state machine (aka syntax charts or -+ * "railroad normal form" in parsing technology). Each node is an opcode -+ * plus a "next" pointer, possibly plus an operand. "Next" pointers of -+ * all nodes except BRANCH implement concatenation; a "next" pointer with -+ * a BRANCH on both ends of it is connecting two alternatives. (Here we -+ * have one of the subtle syntax dependencies: an individual BRANCH (as -+ * opposed to a collection of them) is never concatenated with anything -+ * because of operator precedence.) The operand of some types of node is -+ * a literal string; for others, it is a node leading into a sub-FSM. In -+ * particular, the operand of a BRANCH node is the first node of the branch. -+ * (NB this is *not* a tree structure: the tail of the branch connects -+ * to the thing following the set of BRANCHes.) The opcodes are: -+ */ -+ -+/* definition number opnd? meaning */ -+#define END 0 /* no End of program. */ -+#define BOL 1 /* no Match "" at beginning of line. */ -+#define EOL 2 /* no Match "" at end of line. */ -+#define ANY 3 /* no Match any one character. */ -+#define ANYOF 4 /* str Match any character in this string. */ -+#define ANYBUT 5 /* str Match any character not in this string. */ -+#define BRANCH 6 /* node Match this alternative, or the next... */ -+#define BACK 7 /* no Match "", "next" ptr points backward. */ -+#define EXACTLY 8 /* str Match this string. */ -+#define NOTHING 9 /* no Match empty string. */ -+#define STAR 10 /* node Match this (simple) thing 0 or more times. */ -+#define PLUS 11 /* node Match this (simple) thing 1 or more times. */ -+#define OPEN 20 /* no Mark this point in input as start of #n. */ -+ /* OPEN+1 is number 1, etc. */ -+#define CLOSE 30 /* no Analogous to OPEN. */ -+ -+/* -+ * Opcode notes: -+ * -+ * BRANCH The set of branches constituting a single choice are hooked -+ * together with their "next" pointers, since precedence prevents -+ * anything being concatenated to any individual branch. The -+ * "next" pointer of the last BRANCH in a choice points to the -+ * thing following the whole choice. This is also where the -+ * final "next" pointer of each individual branch points; each -+ * branch starts with the operand node of a BRANCH node. -+ * -+ * BACK Normal "next" pointers all implicitly point forward; BACK -+ * exists to make loop structures possible. -+ * -+ * STAR,PLUS '?', and complex '*' and '+', are implemented as circular -+ * BRANCH structures using BACK. Simple cases (one character -+ * per match) are implemented with STAR and PLUS for speed -+ * and to minimize recursive plunges. -+ * -+ * OPEN,CLOSE ...are numbered at compile time. -+ */ -+ -+/* -+ * A node is one char of opcode followed by two chars of "next" pointer. -+ * "Next" pointers are stored as two 8-bit pieces, high order first. The -+ * value is a positive offset from the opcode of the node containing it. -+ * An operand, if any, simply follows the node. (Note that much of the -+ * code generation knows about this implicit relationship.) -+ * -+ * Using two bytes for the "next" pointer is vast overkill for most things, -+ * but allows patterns to get big without disasters. -+ */ -+#define OP(p) (*(p)) -+#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) -+#define OPERAND(p) ((p) + 3) -+ -+/* -+ * See regmagic.h for one further detail of program structure. -+ */ -+ -+ -+/* -+ * Utility definitions. -+ */ -+#ifndef CHARBITS -+#define UCHARAT(p) ((int)*(unsigned char *)(p)) -+#else -+#define UCHARAT(p) ((int)*(p)&CHARBITS) -+#endif -+ -+#define FAIL(m) { regerror(m); return(NULL); } -+#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') -+#define META "^$.[()|?+*\" -+ -+/* -+ * Flags to be passed up and down. -+ */ -+#define HASWIDTH 01 /* Known never to match null string. */ -+#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ -+#define SPSTART 04 /* Starts with * or +. */ -+#define WORST 0 /* Worst case. */ -+ -+/* -+ * Global work variables for regcomp(). -+ */ -+struct match_globals { -+char *reginput; /* String-input pointer. */ -+char *regbol; /* Beginning of input, for ^ check. */ -+char **regstartp; /* Pointer to startp array. */ -+char **regendp; /* Ditto for endp. */ -+char *regparse; /* Input-scan pointer. */ -+int regnpar; /* () count. */ -+char regdummy; -+char *regcode; /* Code-emit pointer; ®dummy = don't. */ -+long regsize; /* Code size. */ -+}; -+ -+/* -+ * Forward declarations for regcomp()'s friends. -+ */ -+#ifndef STATIC -+#define STATIC static -+#endif -+STATIC char *reg(struct match_globals *g, int paren,int *flagp); -+STATIC char *regbranch(struct match_globals *g, int *flagp); -+STATIC char *regpiece(struct match_globals *g, int *flagp); -+STATIC char *regatom(struct match_globals *g, int *flagp); -+STATIC char *regnode(struct match_globals *g, char op); -+STATIC char *regnext(struct match_globals *g, char *p); -+STATIC void regc(struct match_globals *g, char b); -+STATIC void reginsert(struct match_globals *g, char op, char *opnd); -+STATIC void regtail(struct match_globals *g, char *p, char *val); -+STATIC void regoptail(struct match_globals *g, char *p, char *val); -+ -+ -+__kernel_size_t my_strcspn(const char *s1,const char *s2) -+{ -+ char *scan1; -+ char *scan2; -+ int count; -+ -+ count = 0; -+ for (scan1 = (char *)s1; *scan1 != '\0'; scan1++) { -+ for (scan2 = (char *)s2; *scan2 != '\0';) /* ++ moved down. */ -+ if (*scan1 == *scan2++) -+ return(count); -+ count++; -+ } -+ return(count); -+} -+ -+/* -+ - regcomp - compile a regular expression into internal code -+ * -+ * We can't allocate space until we know how big the compiled form will be, -+ * but we can't compile it (and thus know how big it is) until we've got a -+ * place to put the code. So we cheat: we compile it twice, once with code -+ * generation turned off and size counting turned on, and once "for real". -+ * This also means that we don't allocate space until we are sure that the -+ * thing really will compile successfully, and we never have to move the -+ * code and thus invalidate pointers into it. (Note that it has to be in -+ * one piece because free() must be able to free it all.) -+ * -+ * Beware that the optimization-preparation code in here knows about some -+ * of the structure of the compiled regexp. -+ */ -+regexp * -+regcomp(char *exp,int *patternsize) -+{ -+ register regexp *r; -+ register char *scan; -+ register char *longest; -+ register int len; -+ int flags; -+ struct match_globals g; -+ -+ /* commented out by ethan -+ extern char *malloc(); -+ */ -+ -+ if (exp == NULL) -+ FAIL("NULL argument"); -+ -+ /* First pass: determine size, legality. */ -+ g.regparse = exp; -+ g.regnpar = 1; -+ g.regsize = 0L; -+ g.regcode = &g.regdummy; -+ regc(&g, MAGIC); -+ if (reg(&g, 0, &flags) == NULL) -+ return(NULL); -+ -+ /* Small enough for pointer-storage convention? */ -+ if (g.regsize >= 32767L) /* Probably could be 65535L. */ -+ FAIL("regexp too big"); -+ -+ /* Allocate space. */ -+ *patternsize=sizeof(regexp) + (unsigned)g.regsize; -+ r = (regexp *)malloc(sizeof(regexp) + (unsigned)g.regsize); -+ if (r == NULL) -+ FAIL("out of space"); -+ -+ /* Second pass: emit code. */ -+ g.regparse = exp; -+ g.regnpar = 1; -+ g.regcode = r->program; -+ regc(&g, MAGIC); -+ if (reg(&g, 0, &flags) == NULL) -+ return(NULL); -+ -+ /* Dig out information for optimizations. */ -+ r->regstart = '\0'; /* Worst-case defaults. */ -+ r->reganch = 0; -+ r->regmust = NULL; -+ r->regmlen = 0; -+ scan = r->program+1; /* First BRANCH. */ -+ if (OP(regnext(&g, scan)) == END) { /* Only one top-level choice. */ -+ scan = OPERAND(scan); -+ -+ /* Starting-point info. */ -+ if (OP(scan) == EXACTLY) -+ r->regstart = *OPERAND(scan); -+ else if (OP(scan) == BOL) -+ r->reganch++; -+ -+ /* -+ * If there's something expensive in the r.e., find the -+ * longest literal string that must appear and make it the -+ * regmust. Resolve ties in favor of later strings, since -+ * the regstart check works with the beginning of the r.e. -+ * and avoiding duplication strengthens checking. Not a -+ * strong reason, but sufficient in the absence of others. -+ */ -+ if (flags&SPSTART) { -+ longest = NULL; -+ len = 0; -+ for (; scan != NULL; scan = regnext(&g, scan)) -+ if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { -+ longest = OPERAND(scan); -+ len = strlen(OPERAND(scan)); -+ } -+ r->regmust = longest; -+ r->regmlen = len; -+ } -+ } -+ -+ return(r); -+} -+ -+/* -+ - reg - regular expression, i.e. main body or parenthesized thing -+ * -+ * Caller must absorb opening parenthesis. -+ * -+ * Combining parenthesis handling with the base level of regular expression -+ * is a trifle forced, but the need to tie the tails of the branches to what -+ * follows makes it hard to avoid. -+ */ -+static char * -+reg(struct match_globals *g, int paren, int *flagp /* Parenthesized? */ ) -+{ -+ register char *ret; -+ register char *br; -+ register char *ender; -+ register int parno = 0; /* 0 makes gcc happy */ -+ int flags; -+ -+ *flagp = HASWIDTH; /* Tentatively. */ -+ -+ /* Make an OPEN node, if parenthesized. */ -+ if (paren) { -+ if (g->regnpar >= NSUBEXP) -+ FAIL("too many ()"); -+ parno = g->regnpar; -+ g->regnpar++; -+ ret = regnode(g, OPEN+parno); -+ } else -+ ret = NULL; -+ -+ /* Pick up the branches, linking them together. */ -+ br = regbranch(g, &flags); -+ if (br == NULL) -+ return(NULL); -+ if (ret != NULL) -+ regtail(g, ret, br); /* OPEN -> first. */ -+ else -+ ret = br; -+ if (!(flags&HASWIDTH)) -+ *flagp &= ~HASWIDTH; -+ *flagp |= flags&SPSTART; -+ while (*g->regparse == '|') { -+ g->regparse++; -+ br = regbranch(g, &flags); -+ if (br == NULL) -+ return(NULL); -+ regtail(g, ret, br); /* BRANCH -> BRANCH. */ -+ if (!(flags&HASWIDTH)) -+ *flagp &= ~HASWIDTH; -+ *flagp |= flags&SPSTART; -+ } -+ -+ /* Make a closing node, and hook it on the end. */ -+ ender = regnode(g, (paren) ? CLOSE+parno : END); -+ regtail(g, ret, ender); -+ -+ /* Hook the tails of the branches to the closing node. */ -+ for (br = ret; br != NULL; br = regnext(g, br)) -+ regoptail(g, br, ender); -+ -+ /* Check for proper termination. */ -+ if (paren && *g->regparse++ != ')') { -+ FAIL("unmatched ()"); -+ } else if (!paren && *g->regparse != '\0') { -+ if (*g->regparse == ')') { -+ FAIL("unmatched ()"); -+ } else -+ FAIL("junk on end"); /* "Can't happen". */ -+ /* NOTREACHED */ -+ } -+ -+ return(ret); -+} -+ -+/* -+ - regbranch - one alternative of an | operator -+ * -+ * Implements the concatenation operator. -+ */ -+static char * -+regbranch(struct match_globals *g, int *flagp) -+{ -+ register char *ret; -+ register char *chain; -+ register char *latest; -+ int flags; -+ -+ *flagp = WORST; /* Tentatively. */ -+ -+ ret = regnode(g, BRANCH); -+ chain = NULL; -+ while (*g->regparse != '\0' && *g->regparse != '|' && *g->regparse != ')') { -+ latest = regpiece(g, &flags); -+ if (latest == NULL) -+ return(NULL); -+ *flagp |= flags&HASWIDTH; -+ if (chain == NULL) /* First piece. */ -+ *flagp |= flags&SPSTART; -+ else -+ regtail(g, chain, latest); -+ chain = latest; -+ } -+ if (chain == NULL) /* Loop ran zero times. */ -+ (void) regnode(g, NOTHING); -+ -+ return(ret); -+} -+ -+/* -+ - regpiece - something followed by possible [*+?] -+ * -+ * Note that the branching code sequences used for ? and the general cases -+ * of * and + are somewhat optimized: they use the same NOTHING node as -+ * both the endmarker for their branch list and the body of the last branch. -+ * It might seem that this node could be dispensed with entirely, but the -+ * endmarker role is not redundant. -+ */ -+static char * -+regpiece(struct match_globals *g, int *flagp) -+{ -+ register char *ret; -+ register char op; -+ register char *next; -+ int flags; -+ -+ ret = regatom(g, &flags); -+ if (ret == NULL) -+ return(NULL); -+ -+ op = *g->regparse; -+ if (!ISMULT(op)) { -+ *flagp = flags; -+ return(ret); -+ } -+ -+ if (!(flags&HASWIDTH) && op != '?') -+ FAIL("*+ operand could be empty"); -+ *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); -+ -+ if (op == '*' && (flags&SIMPLE)) -+ reginsert(g, STAR, ret); -+ else if (op == '*') { -+ /* Emit x* as (x&|), where & means "self". */ -+ reginsert(g, BRANCH, ret); /* Either x */ -+ regoptail(g, ret, regnode(g, BACK)); /* and loop */ -+ regoptail(g, ret, ret); /* back */ -+ regtail(g, ret, regnode(g, BRANCH)); /* or */ -+ regtail(g, ret, regnode(g, NOTHING)); /* null. */ -+ } else if (op == '+' && (flags&SIMPLE)) -+ reginsert(g, PLUS, ret); -+ else if (op == '+') { -+ /* Emit x+ as x(&|), where & means "self". */ -+ next = regnode(g, BRANCH); /* Either */ -+ regtail(g, ret, next); -+ regtail(g, regnode(g, BACK), ret); /* loop back */ -+ regtail(g, next, regnode(g, BRANCH)); /* or */ -+ regtail(g, ret, regnode(g, NOTHING)); /* null. */ -+ } else if (op == '?') { -+ /* Emit x? as (x|) */ -+ reginsert(g, BRANCH, ret); /* Either x */ -+ regtail(g, ret, regnode(g, BRANCH)); /* or */ -+ next = regnode(g, NOTHING); /* null. */ -+ regtail(g, ret, next); -+ regoptail(g, ret, next); -+ } -+ g->regparse++; -+ if (ISMULT(*g->regparse)) -+ FAIL("nested *?+"); -+ -+ return(ret); -+} -+ -+/* -+ - regatom - the lowest level -+ * -+ * Optimization: gobbles an entire sequence of ordinary characters so that -+ * it can turn them into a single node, which is smaller to store and -+ * faster to run. Backslashed characters are exceptions, each becoming a -+ * separate node; the code is simpler that way and it's not worth fixing. -+ */ -+static char * -+regatom(struct match_globals *g, int *flagp) -+{ -+ register char *ret; -+ int flags; -+ -+ *flagp = WORST; /* Tentatively. */ -+ -+ switch (*g->regparse++) { -+ case '^': -+ ret = regnode(g, BOL); -+ break; -+ case '$': -+ ret = regnode(g, EOL); -+ break; -+ case '.': -+ ret = regnode(g, ANY); -+ *flagp |= HASWIDTH|SIMPLE; -+ break; -+ case '[': { -+ register int class; -+ register int classend; -+ -+ if (*g->regparse == '^') { /* Complement of range. */ -+ ret = regnode(g, ANYBUT); -+ g->regparse++; -+ } else -+ ret = regnode(g, ANYOF); -+ if (*g->regparse == ']' || *g->regparse == '-') -+ regc(g, *g->regparse++); -+ while (*g->regparse != '\0' && *g->regparse != ']') { -+ if (*g->regparse == '-') { -+ g->regparse++; -+ if (*g->regparse == ']' || *g->regparse == '\0') -+ regc(g, '-'); -+ else { -+ class = UCHARAT(g->regparse-2)+1; -+ classend = UCHARAT(g->regparse); -+ if (class > classend+1) -+ FAIL("invalid [] range"); -+ for (; class <= classend; class++) -+ regc(g, class); -+ g->regparse++; -+ } -+ } else -+ regc(g, *g->regparse++); -+ } -+ regc(g, '\0'); -+ if (*g->regparse != ']') -+ FAIL("unmatched []"); -+ g->regparse++; -+ *flagp |= HASWIDTH|SIMPLE; -+ } -+ break; -+ case '(': -+ ret = reg(g, 1, &flags); -+ if (ret == NULL) -+ return(NULL); -+ *flagp |= flags&(HASWIDTH|SPSTART); -+ break; -+ case '\0': -+ case '|': -+ case ')': -+ FAIL("internal urp"); /* Supposed to be caught earlier. */ -+ break; -+ case '?': -+ case '+': -+ case '*': -+ FAIL("?+* follows nothing"); -+ break; -+ case '\': -+ if (*g->regparse == '\0') -+ FAIL("trailing \"); -+ ret = regnode(g, EXACTLY); -+ regc(g, *g->regparse++); -+ regc(g, '\0'); -+ *flagp |= HASWIDTH|SIMPLE; -+ break; -+ default: { -+ register int len; -+ register char ender; -+ -+ g->regparse--; -+ len = my_strcspn((const char *)g->regparse, (const char *)META); -+ if (len <= 0) -+ FAIL("internal disaster"); -+ ender = *(g->regparse+len); -+ if (len > 1 && ISMULT(ender)) -+ len--; /* Back off clear of ?+* operand. */ -+ *flagp |= HASWIDTH; -+ if (len == 1) -+ *flagp |= SIMPLE; -+ ret = regnode(g, EXACTLY); -+ while (len > 0) { -+ regc(g, *g->regparse++); -+ len--; -+ } -+ regc(g, '\0'); -+ } -+ break; -+ } -+ -+ return(ret); -+} -+ -+/* -+ - regnode - emit a node -+ */ -+static char * /* Location. */ -+regnode(struct match_globals *g, char op) -+{ -+ register char *ret; -+ register char *ptr; -+ -+ ret = g->regcode; -+ if (ret == &g->regdummy) { -+ g->regsize += 3; -+ return(ret); -+ } -+ -+ ptr = ret; -+ *ptr++ = op; -+ *ptr++ = '\0'; /* Null "next" pointer. */ -+ *ptr++ = '\0'; -+ g->regcode = ptr; -+ -+ return(ret); -+} -+ -+/* -+ - regc - emit (if appropriate) a byte of code -+ */ -+static void -+regc(struct match_globals *g, char b) -+{ -+ if (g->regcode != &g->regdummy) -+ *g->regcode++ = b; -+ else -+ g->regsize++; -+} -+ -+/* -+ - reginsert - insert an operator in front of already-emitted operand -+ * -+ * Means relocating the operand. -+ */ -+static void -+reginsert(struct match_globals *g, char op, char* opnd) -+{ -+ register char *src; -+ register char *dst; -+ register char *place; -+ -+ if (g->regcode == &g->regdummy) { -+ g->regsize += 3; -+ return; -+ } -+ -+ src = g->regcode; -+ g->regcode += 3; -+ dst = g->regcode; -+ while (src > opnd) -+ *--dst = *--src; -+ -+ place = opnd; /* Op node, where operand used to be. */ -+ *place++ = op; -+ *place++ = '\0'; -+ *place++ = '\0'; -+} -+ -+/* -+ - regtail - set the next-pointer at the end of a node chain -+ */ -+static void -+regtail(struct match_globals *g, char *p, char *val) -+{ -+ register char *scan; -+ register char *temp; -+ register int offset; -+ -+ if (p == &g->regdummy) -+ return; -+ -+ /* Find last node. */ -+ scan = p; -+ for (;;) { -+ temp = regnext(g, scan); -+ if (temp == NULL) -+ break; -+ scan = temp; -+ } -+ -+ if (OP(scan) == BACK) -+ offset = scan - val; -+ else -+ offset = val - scan; -+ *(scan+1) = (offset>>8)&0377; -+ *(scan+2) = offset&0377; -+} -+ -+/* -+ - regoptail - regtail on operand of first argument; nop if operandless -+ */ -+static void -+regoptail(struct match_globals *g, char *p, char *val) -+{ -+ /* "Operandless" and "op != BRANCH" are synonymous in practice. */ -+ if (p == NULL || p == &g->regdummy || OP(p) != BRANCH) -+ return; -+ regtail(g, OPERAND(p), val); -+} -+ -+/* -+ * regexec and friends -+ */ -+ -+ -+/* -+ * Forwards. -+ */ -+STATIC int regtry(struct match_globals *g, regexp *prog, char *string); -+STATIC int regmatch(struct match_globals *g, char *prog); -+STATIC int regrepeat(struct match_globals *g, char *p); -+ -+#ifdef DEBUG -+int regnarrate = 0; -+void regdump(); -+STATIC char *regprop(char *op); -+#endif -+ -+/* -+ - regexec - match a regexp against a string -+ */ -+int -+regexec(regexp *prog, char *string) -+{ -+ register char *s; -+ struct match_globals g; -+ -+ /* Be paranoid... */ -+ if (prog == NULL || string == NULL) { -+ printk("<3>Regexp: NULL parameter\n"); -+ return(0); -+ } -+ -+ /* Check validity of program. */ -+ if (UCHARAT(prog->program) != MAGIC) { -+ printk("<3>Regexp: corrupted program\n"); -+ return(0); -+ } -+ -+ /* If there is a "must appear" string, look for it. */ -+ if (prog->regmust != NULL) { -+ s = string; -+ while ((s = strchr(s, prog->regmust[0])) != NULL) { -+ if (strncmp(s, prog->regmust, prog->regmlen) == 0) -+ break; /* Found it. */ -+ s++; -+ } -+ if (s == NULL) /* Not present. */ -+ return(0); -+ } -+ -+ /* Mark beginning of line for ^ . */ -+ g.regbol = string; -+ -+ /* Simplest case: anchored match need be tried only once. */ -+ if (prog->reganch) -+ return(regtry(&g, prog, string)); -+ -+ /* Messy cases: unanchored match. */ -+ s = string; -+ if (prog->regstart != '\0') -+ /* We know what char it must start with. */ -+ while ((s = strchr(s, prog->regstart)) != NULL) { -+ if (regtry(&g, prog, s)) -+ return(1); -+ s++; -+ } -+ else -+ /* We don't -- general case. */ -+ do { -+ if (regtry(&g, prog, s)) -+ return(1); -+ } while (*s++ != '\0'); -+ -+ /* Failure. */ -+ return(0); -+} -+ -+/* -+ - regtry - try match at specific point -+ */ -+static int /* 0 failure, 1 success */ -+regtry(struct match_globals *g, regexp *prog, char *string) -+{ -+ register int i; -+ register char **sp; -+ register char **ep; -+ -+ g->reginput = string; -+ g->regstartp = prog->startp; -+ g->regendp = prog->endp; -+ -+ sp = prog->startp; -+ ep = prog->endp; -+ for (i = NSUBEXP; i > 0; i--) { -+ *sp++ = NULL; -+ *ep++ = NULL; -+ } -+ if (regmatch(g, prog->program + 1)) { -+ prog->startp[0] = string; -+ prog->endp[0] = g->reginput; -+ return(1); -+ } else -+ return(0); -+} -+ -+/* -+ - regmatch - main matching routine -+ * -+ * Conceptually the strategy is simple: check to see whether the current -+ * node matches, call self recursively to see whether the rest matches, -+ * and then act accordingly. In practice we make some effort to avoid -+ * recursion, in particular by going through "ordinary" nodes (that don't -+ * need to know whether the rest of the match failed) by a loop instead of -+ * by recursion. -+ */ -+static int /* 0 failure, 1 success */ -+regmatch(struct match_globals *g, char *prog) -+{ -+ register char *scan = prog; /* Current node. */ -+ char *next; /* Next node. */ -+ -+#ifdef DEBUG -+ if (scan != NULL && regnarrate) -+ fprintf(stderr, "%s(\n", regprop(scan)); -+#endif -+ while (scan != NULL) { -+#ifdef DEBUG -+ if (regnarrate) -+ fprintf(stderr, "%s...\n", regprop(scan)); -+#endif -+ next = regnext(g, scan); -+ -+ switch (OP(scan)) { -+ case BOL: -+ if (g->reginput != g->regbol) -+ return(0); -+ break; -+ case EOL: -+ if (*g->reginput != '\0') -+ return(0); -+ break; -+ case ANY: -+ if (*g->reginput == '\0') -+ return(0); -+ g->reginput++; -+ break; -+ case EXACTLY: { -+ register int len; -+ register char *opnd; -+ -+ opnd = OPERAND(scan); -+ /* Inline the first character, for speed. */ -+ if (*opnd != *g->reginput) -+ return(0); -+ len = strlen(opnd); -+ if (len > 1 && strncmp(opnd, g->reginput, len) != 0) -+ return(0); -+ g->reginput += len; -+ } -+ break; -+ case ANYOF: -+ if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) == NULL) -+ return(0); -+ g->reginput++; -+ break; -+ case ANYBUT: -+ if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) != NULL) -+ return(0); -+ g->reginput++; -+ break; -+ case NOTHING: -+ case BACK: -+ break; -+ case OPEN+1: -+ case OPEN+2: -+ case OPEN+3: -+ case OPEN+4: -+ case OPEN+5: -+ case OPEN+6: -+ case OPEN+7: -+ case OPEN+8: -+ case OPEN+9: { -+ register int no; -+ register char *save; -+ -+ no = OP(scan) - OPEN; -+ save = g->reginput; -+ -+ if (regmatch(g, next)) { -+ /* -+ * Don't set startp if some later -+ * invocation of the same parentheses -+ * already has. -+ */ -+ if (g->regstartp[no] == NULL) -+ g->regstartp[no] = save; -+ return(1); -+ } else -+ return(0); -+ } -+ break; -+ case CLOSE+1: -+ case CLOSE+2: -+ case CLOSE+3: -+ case CLOSE+4: -+ case CLOSE+5: -+ case CLOSE+6: -+ case CLOSE+7: -+ case CLOSE+8: -+ case CLOSE+9: -+ { -+ register int no; -+ register char *save; -+ -+ no = OP(scan) - CLOSE; -+ save = g->reginput; -+ -+ if (regmatch(g, next)) { -+ /* -+ * Don't set endp if some later -+ * invocation of the same parentheses -+ * already has. -+ */ -+ if (g->regendp[no] == NULL) -+ g->regendp[no] = save; -+ return(1); -+ } else -+ return(0); -+ } -+ break; -+ case BRANCH: { -+ register char *save; -+ -+ if (OP(next) != BRANCH) /* No choice. */ -+ next = OPERAND(scan); /* Avoid recursion. */ -+ else { -+ do { -+ save = g->reginput; -+ if (regmatch(g, OPERAND(scan))) -+ return(1); -+ g->reginput = save; -+ scan = regnext(g, scan); -+ } while (scan != NULL && OP(scan) == BRANCH); -+ return(0); -+ /* NOTREACHED */ -+ } -+ } -+ break; -+ case STAR: -+ case PLUS: { -+ register char nextch; -+ register int no; -+ register char *save; -+ register int min; -+ -+ /* -+ * Lookahead to avoid useless match attempts -+ * when we know what character comes next. -+ */ -+ nextch = '\0'; -+ if (OP(next) == EXACTLY) -+ nextch = *OPERAND(next); -+ min = (OP(scan) == STAR) ? 0 : 1; -+ save = g->reginput; -+ no = regrepeat(g, OPERAND(scan)); -+ while (no >= min) { -+ /* If it could work, try it. */ -+ if (nextch == '\0' || *g->reginput == nextch) -+ if (regmatch(g, next)) -+ return(1); -+ /* Couldn't or didn't -- back up. */ -+ no--; -+ g->reginput = save + no; -+ } -+ return(0); -+ } -+ break; -+ case END: -+ return(1); /* Success! */ -+ break; -+ default: -+ printk("<3>Regexp: memory corruption\n"); -+ return(0); -+ break; -+ } -+ -+ scan = next; -+ } -+ -+ /* -+ * We get here only if there's trouble -- normally "case END" is -+ * the terminating point. -+ */ -+ printk("<3>Regexp: corrupted pointers\n"); -+ return(0); -+} -+ -+/* -+ - regrepeat - repeatedly match something simple, report how many -+ */ -+static int -+regrepeat(struct match_globals *g, char *p) -+{ -+ register int count = 0; -+ register char *scan; -+ register char *opnd; -+ -+ scan = g->reginput; -+ opnd = OPERAND(p); -+ switch (OP(p)) { -+ case ANY: -+ count = strlen(scan); -+ scan += count; -+ break; -+ case EXACTLY: -+ while (*opnd == *scan) { -+ count++; -+ scan++; -+ } -+ break; -+ case ANYOF: -+ while (*scan != '\0' && strchr(opnd, *scan) != NULL) { -+ count++; -+ scan++; -+ } -+ break; -+ case ANYBUT: -+ while (*scan != '\0' && strchr(opnd, *scan) == NULL) { -+ count++; -+ scan++; -+ } -+ break; -+ default: /* Oh dear. Called inappropriately. */ -+ printk("<3>Regexp: internal foulup\n"); -+ count = 0; /* Best compromise. */ -+ break; -+ } -+ g->reginput = scan; -+ -+ return(count); -+} -+ -+/* -+ - regnext - dig the "next" pointer out of a node -+ */ -+static char* -+regnext(struct match_globals *g, char *p) -+{ -+ register int offset; -+ -+ if (p == &g->regdummy) -+ return(NULL); -+ -+ offset = NEXT(p); -+ if (offset == 0) -+ return(NULL); -+ -+ if (OP(p) == BACK) -+ return(p-offset); -+ else -+ return(p+offset); -+} -+ -+#ifdef DEBUG -+ -+STATIC char *regprop(); -+ -+/* -+ - regdump - dump a regexp onto stdout in vaguely comprehensible form -+ */ -+void -+regdump(regexp *r) -+{ -+ register char *s; -+ register char op = EXACTLY; /* Arbitrary non-END op. */ -+ register char *next; -+ /* extern char *strchr(); */ -+ -+ -+ s = r->program + 1; -+ while (op != END) { /* While that wasn't END last time... */ -+ op = OP(s); -+ printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ -+ next = regnext(s); -+ if (next == NULL) /* Next ptr. */ -+ printf("(0)"); -+ else -+ printf("(%d)", (s-r->program)+(next-s)); -+ s += 3; -+ if (op == ANYOF || op == ANYBUT || op == EXACTLY) { -+ /* Literal string, where present. */ -+ while (*s != '\0') { -+ putchar(*s); -+ s++; -+ } -+ s++; -+ } -+ putchar('\n'); -+ } -+ -+ /* Header fields of interest. */ -+ if (r->regstart != '\0') -+ printf("start `%c' ", r->regstart); -+ if (r->reganch) -+ printf("anchored "); -+ if (r->regmust != NULL) -+ printf("must have "%s"", r->regmust); -+ printf("\n"); -+} -+ -+/* -+ - regprop - printable representation of opcode -+ */ -+static char * -+regprop(char *op) -+{ -+#define BUFLEN 50 -+ register char *p; -+ static char buf[BUFLEN]; -+ -+ strcpy(buf, ":"); -+ -+ switch (OP(op)) { -+ case BOL: -+ p = "BOL"; -+ break; -+ case EOL: -+ p = "EOL"; -+ break; -+ case ANY: -+ p = "ANY"; -+ break; -+ case ANYOF: -+ p = "ANYOF"; -+ break; -+ case ANYBUT: -+ p = "ANYBUT"; -+ break; -+ case BRANCH: -+ p = "BRANCH"; -+ break; -+ case EXACTLY: -+ p = "EXACTLY"; -+ break; -+ case NOTHING: -+ p = "NOTHING"; -+ break; -+ case BACK: -+ p = "BACK"; -+ break; -+ case END: -+ p = "END"; -+ break; -+ case OPEN+1: -+ case OPEN+2: -+ case OPEN+3: -+ case OPEN+4: -+ case OPEN+5: -+ case OPEN+6: -+ case OPEN+7: -+ case OPEN+8: -+ case OPEN+9: -+ snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "OPEN%d", OP(op)-OPEN); -+ p = NULL; -+ break; -+ case CLOSE+1: -+ case CLOSE+2: -+ case CLOSE+3: -+ case CLOSE+4: -+ case CLOSE+5: -+ case CLOSE+6: -+ case CLOSE+7: -+ case CLOSE+8: -+ case CLOSE+9: -+ snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "CLOSE%d", OP(op)-CLOSE); -+ p = NULL; -+ break; -+ case STAR: -+ p = "STAR"; -+ break; -+ case PLUS: -+ p = "PLUS"; -+ break; -+ default: -+ printk("<3>Regexp: corrupted opcode\n"); -+ break; -+ } -+ if (p != NULL) -+ strncat(buf, p, BUFLEN-strlen(buf)); -+ return(buf); -+} -+#endif -+ -+ -diff -Naur linux-3.0.24.org/net/netfilter/regexp/regexp.h linux-3.0.24/net/netfilter/regexp/regexp.h ---- linux-3.0.24.org/net/netfilter/regexp/regexp.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.0.24/net/netfilter/regexp/regexp.h 2012-03-15 20:08:49.066043520 +0100 -@@ -0,0 +1,41 @@ -+/* -+ * Definitions etc. for regexp(3) routines. -+ * -+ * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], -+ * not the System V one. -+ */ -+ -+#ifndef REGEXP_H -+#define REGEXP_H -+ -+ -+/* -+http://www.opensource.apple.com/darwinsource/10.3/expect-1/expect/expect.h , -+which contains a version of this library, says: -+ -+ * -+ * NSUBEXP must be at least 10, and no greater than 117 or the parser -+ * will not work properly. -+ * -+ -+However, it looks rather like this library is limited to 10. If you think -+otherwise, let us know. -+*/ -+ -+#define NSUBEXP 10 -+typedef struct regexp { -+ char *startp[NSUBEXP]; -+ char *endp[NSUBEXP]; -+ char regstart; /* Internal use only. */ -+ char reganch; /* Internal use only. */ -+ char *regmust; /* Internal use only. */ -+ int regmlen; /* Internal use only. */ -+ char program[1]; /* Unwarranted chumminess with compiler. */ -+} regexp; -+ -+regexp * regcomp(char *exp, int *patternsize); -+int regexec(regexp *prog, char *string); -+void regsub(regexp *prog, char *source, char *dest); -+void regerror(char *s); -+ -+#endif -diff -Naur linux-3.0.24.org/net/netfilter/regexp/regmagic.h linux-3.0.24/net/netfilter/regexp/regmagic.h ---- linux-3.0.24.org/net/netfilter/regexp/regmagic.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.0.24/net/netfilter/regexp/regmagic.h 2012-03-15 20:08:49.066043520 +0100 -@@ -0,0 +1,5 @@ -+/* -+ * The first byte of the regexp internal "program" is actually this magic -+ * number; the start node begins in the second byte. -+ */ -+#define MAGIC 0234 -diff -Naur linux-3.0.24.org/net/netfilter/regexp/regsub.c linux-3.0.24/net/netfilter/regexp/regsub.c ---- linux-3.0.24.org/net/netfilter/regexp/regsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.0.24/net/netfilter/regexp/regsub.c 2012-03-15 20:08:49.076047746 +0100 -@@ -0,0 +1,95 @@ -+/* -+ * regsub -+ * @(#)regsub.c 1.3 of 2 April 86 -+ * -+ * Copyright (c) 1986 by University of Toronto. -+ * Written by Henry Spencer. Not derived from licensed software. -+ * -+ * Permission is granted to anyone to use this software for any -+ * purpose on any computer system, and to redistribute it freely, -+ * subject to the following restrictions: -+ * -+ * 1. The author is not responsible for the consequences of use of -+ * this software, no matter how awful, even if they arise -+ * from defects in it. -+ * -+ * 2. The origin of this software must not be misrepresented, either -+ * by explicit claim or by omission. -+ * -+ * 3. Altered versions must be plainly marked as such, and must not -+ * be misrepresented as being the original software. -+ * -+ * -+ * This code was modified by Ethan Sommer to work within the kernel -+ * (it now uses kmalloc etc..) -+ * -+ */ -+#include "regexp.h" -+#include "regmagic.h" -+#include <linux/string.h> -+ -+ -+#ifndef CHARBITS -+#define UCHARAT(p) ((int)*(unsigned char *)(p)) -+#else -+#define UCHARAT(p) ((int)*(p)&CHARBITS) -+#endif -+ -+#if 0 -+//void regerror(char * s) -+//{ -+// printk("regexp(3): %s", s); -+// /* NOTREACHED */ -+//} -+#endif -+ -+/* -+ - regsub - perform substitutions after a regexp match -+ */ -+void -+regsub(regexp * prog, char * source, char * dest) -+{ -+ register char *src; -+ register char *dst; -+ register char c; -+ register int no; -+ register int len; -+ -+ /* Not necessary and gcc doesn't like it -MLS */ -+ /*extern char *strncpy();*/ -+ -+ if (prog == NULL || source == NULL || dest == NULL) { -+ regerror("NULL parm to regsub"); -+ return; -+ } -+ if (UCHARAT(prog->program) != MAGIC) { -+ regerror("damaged regexp fed to regsub"); -+ return; -+ } -+ -+ src = source; -+ dst = dest; -+ while ((c = *src++) != '\0') { -+ if (c == '&') -+ no = 0; -+ else if (c == '\' && '0' <= *src && *src <= '9') -+ no = *src++ - '0'; -+ else -+ no = -1; -+ -+ if (no < 0) { /* Ordinary character. */ -+ if (c == '\' && (*src == '\' || *src == '&')) -+ c = *src++; -+ *dst++ = c; -+ } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) { -+ len = prog->endp[no] - prog->startp[no]; -+ (void) strncpy(dst, prog->startp[no], len); -+ dst += len; -+ if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */ -+ regerror("damaged match string"); -+ return; -+ } -+ } -+ } -+ *dst++ = '\0'; -+} -diff -Naur linux-3.0.24.org/net/netfilter/xt_layer7.c linux-3.0.24/net/netfilter/xt_layer7.c ---- linux-3.0.24.org/net/netfilter/xt_layer7.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.0.24/net/netfilter/xt_layer7.c 2012-03-20 01:44:50.907527097 +0100 -@@ -0,0 +1,684 @@ -+/* -+ Kernel module to match application layer (OSI layer 7) data in connections. -+ -+ http://l7-filter.sf.net -+ -+ (C) 2003-2009 Matthew Strait and Ethan Sommer. -+ -+ 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. -+ http://www.gnu.org/licenses/gpl.txt -+ -+ Based on ipt_string.c (C) 2000 Emmanuel Roger winfield@freegates.be, -+ xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait, -+ Ethan Sommer, Justin Levandoski. -+*/ -+ -+#include <linux/spinlock.h> -+#include <linux/version.h> -+#include <net/ip.h> -+#include <net/tcp.h> -+#include <linux/module.h> -+#include <linux/skbuff.h> -+#include <linux/netfilter.h> -+#include <net/netfilter/nf_conntrack.h> -+#include <net/netfilter/nf_conntrack_core.h> -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -+#include <net/netfilter/nf_conntrack_extend.h> -+#include <net/netfilter/nf_conntrack_acct.h> -+#endif -+#include <linux/netfilter/x_tables.h> -+#include <linux/netfilter/xt_layer7.h> -+#include <linux/ctype.h> -+#include <linux/proc_fs.h> -+ -+#include "regexp/regexp.c" -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Matthew Strait quadong@users.sf.net, Ethan Sommer sommere@users.sf.net"); -+MODULE_DESCRIPTION("iptables application layer match module"); -+MODULE_ALIAS("ipt_layer7"); -+MODULE_VERSION("2.22ipfire"); -+ -+static int maxdatalen = 2048; // this is the default -+module_param(maxdatalen, int, 0444); -+MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter"); -+#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG -+ #define DPRINTK(format,args...) printk(format,##args) -+#else -+ #define DPRINTK(format,args...) -+#endif -+ -+/* Number of packets whose data we look at. -+This can be modified through /proc/net/layer7_numpackets */ -+static int num_packets = 10; -+ -+static struct pattern_cache { -+ char * regex_string; -+ regexp * pattern; -+ struct pattern_cache * next; -+} * first_pattern_cache = NULL; -+ -+DEFINE_SPINLOCK(l7_lock); -+ -+static int total_acct_packets(struct nf_conn *ct) -+{ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26) -+ BUG_ON(ct == NULL); -+ return (ct->counters[IP_CT_DIR_ORIGINAL].packets + ct->counters[IP_CT_DIR_REPLY].packets); -+#else -+ struct nf_conn_counter *acct; -+ -+ BUG_ON(ct == NULL); -+ acct = nf_conn_acct_find(ct); -+ if (!acct) -+ return 0; -+ return (acct[IP_CT_DIR_ORIGINAL].packets + acct[IP_CT_DIR_REPLY].packets); -+#endif -+} -+ -+#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG -+/* Converts an unfriendly string into a friendly one by -+replacing unprintables with periods and all whitespace with " ". */ -+static char * friendly_print(unsigned char * s) -+{ -+ char * f = kmalloc(strlen(s) + 1, GFP_ATOMIC); -+ int i; -+ -+ if(!f) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "friendly_print, bailing.\n"); -+ return NULL; -+ } -+ -+ for(i = 0; i < strlen(s); i++){ -+ if(isprint(s[i]) && s[i] < 128) f[i] = s[i]; -+ else if(isspace(s[i])) f[i] = ' '; -+ else f[i] = '.'; -+ } -+ f[i] = '\0'; -+ return f; -+} -+ -+static char dec2hex(int i) -+{ -+ switch (i) { -+ case 0 ... 9: -+ return (i + '0'); -+ break; -+ case 10 ... 15: -+ return (i - 10 + 'a'); -+ break; -+ default: -+ if (net_ratelimit()) -+ printk("layer7: Problem in dec2hex\n"); -+ return '\0'; -+ } -+} -+ -+static char * hex_print(unsigned char * s) -+{ -+ char * g = kmalloc(strlen(s)*3 + 1, GFP_ATOMIC); -+ int i; -+ -+ if(!g) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in hex_print, " -+ "bailing.\n"); -+ return NULL; -+ } -+ -+ for(i = 0; i < strlen(s); i++) { -+ g[i*3 ] = dec2hex(s[i]/16); -+ g[i*3 + 1] = dec2hex(s[i]%16); -+ g[i*3 + 2] = ' '; -+ } -+ g[i*3] = '\0'; -+ -+ return g; -+} -+#endif // DEBUG -+ -+/* Use instead of regcomp. As we expect to be seeing the same regexps over and -+over again, it make sense to cache the results. */ -+static regexp * compile_and_cache(const char * regex_string, -+ const char * protocol) -+{ -+ struct pattern_cache * node = first_pattern_cache; -+ struct pattern_cache * last_pattern_cache = first_pattern_cache; -+ struct pattern_cache * tmp; -+ unsigned int len; -+ -+ while (node != NULL) { -+ if (!strcmp(node->regex_string, regex_string)) -+ return node->pattern; -+ -+ last_pattern_cache = node;/* points at the last non-NULL node */ -+ node = node->next; -+ } -+ -+ /* If we reach the end of the list, then we have not yet cached -+ the pattern for this regex. Let's do that now. -+ Be paranoid about running out of memory to avoid list corruption. */ -+ tmp = kmalloc(sizeof(struct pattern_cache), GFP_ATOMIC); -+ -+ if(!tmp) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "compile_and_cache, bailing.\n"); -+ return NULL; -+ } -+ -+ tmp->regex_string = kmalloc(strlen(regex_string) + 1, GFP_ATOMIC); -+ tmp->pattern = kmalloc(sizeof(struct regexp), GFP_ATOMIC); -+ tmp->next = NULL; -+ -+ if(!tmp->regex_string || !tmp->pattern) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "compile_and_cache, bailing.\n"); -+ kfree(tmp->regex_string); -+ kfree(tmp->pattern); -+ kfree(tmp); -+ return NULL; -+ } -+ -+ /* Ok. The new node is all ready now. */ -+ node = tmp; -+ -+ if(first_pattern_cache == NULL) /* list is empty */ -+ first_pattern_cache = node; /* make node the beginning */ -+ else -+ last_pattern_cache->next = node; /* attach node to the end */ -+ -+ /* copy the string and compile the regex */ -+ len = strlen(regex_string); -+ DPRINTK("layer7: about to compile this: "%s"\n", regex_string); -+ node->pattern = regcomp((char *)regex_string, &len); -+ if ( !node->pattern ) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: Error compiling regexp " -+ ""%s" (%s)\n", -+ regex_string, protocol); -+ /* pattern is now cached as NULL, so we won't try again. */ -+ } -+ -+ strcpy(node->regex_string, regex_string); -+ return node->pattern; -+} -+ -+static int can_handle(const struct sk_buff *skb) -+{ -+ if(!ip_hdr(skb)) /* not IP */ -+ return 0; -+ if(ip_hdr(skb)->protocol != IPPROTO_TCP && -+ ip_hdr(skb)->protocol != IPPROTO_UDP && -+ ip_hdr(skb)->protocol != IPPROTO_ICMP) -+ return 0; -+ return 1; -+} -+ -+/* Returns offset the into the skb->data that the application data starts */ -+static int app_data_offset(const struct sk_buff *skb) -+{ -+ /* In case we are ported somewhere (ebtables?) where ip_hdr(skb) -+ isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */ -+ int ip_hl = 4*ip_hdr(skb)->ihl; -+ -+ if( ip_hdr(skb)->protocol == IPPROTO_TCP ) { -+ /* 12 == offset into TCP header for the header length field. -+ Can't get this with skb->h.th->doff because the tcphdr -+ struct doesn't get set when routing (this is confirmed to be -+ true in Netfilter as well as QoS.) */ -+ int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4); -+ -+ return ip_hl + tcp_hl; -+ } else if( ip_hdr(skb)->protocol == IPPROTO_UDP ) { -+ return ip_hl + 8; /* UDP header is always 8 bytes */ -+ } else if( ip_hdr(skb)->protocol == IPPROTO_ICMP ) { -+ return ip_hl + 8; /* ICMP header is 8 bytes */ -+ } else { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: tried to handle unknown " -+ "protocol!\n"); -+ return ip_hl + 8; /* something reasonable */ -+ } -+} -+ -+/* handles whether there's a match when we aren't appending data anymore */ -+static int match_no_append(struct nf_conn * conntrack, -+ struct nf_conn * master_conntrack, -+ enum ip_conntrack_info ctinfo, -+ enum ip_conntrack_info master_ctinfo, -+ const struct xt_layer7_info * info) -+{ -+ /* If we're in here, throw the app data away */ -+ if(master_conntrack->layer7.app_data != NULL) { -+ -+ #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG -+ if(!master_conntrack->layer7.app_proto) { -+ char * f = -+ friendly_print(master_conntrack->layer7.app_data); -+ char * g = -+ hex_print(master_conntrack->layer7.app_data); -+ DPRINTK("\nl7-filter gave up after %d bytes " -+ "(%d packets):\n%s\n", -+ strlen(f), total_acct_packets(master_conntrack), f); -+ kfree(f); -+ DPRINTK("In hex: %s\n", g); -+ kfree(g); -+ } -+ #endif -+ -+ kfree(master_conntrack->layer7.app_data); -+ master_conntrack->layer7.app_data = NULL; /* don't free again */ -+ } -+ -+ if(master_conntrack->layer7.app_proto){ -+ /* Here child connections set their .app_proto (for /proc) */ -+ if(!conntrack->layer7.app_proto) { -+ conntrack->layer7.app_proto = -+ kmalloc(strlen(master_conntrack->layer7.app_proto)+1, -+ GFP_ATOMIC); -+ if(!conntrack->layer7.app_proto){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory " -+ "in match_no_append, " -+ "bailing.\n"); -+ return 1; -+ } -+ strcpy(conntrack->layer7.app_proto, -+ master_conntrack->layer7.app_proto); -+ } -+ -+ return (!strcmp(master_conntrack->layer7.app_proto, -+ info->protocol)); -+ } -+ else { -+ /* If not classified, set to "unknown" to distinguish from -+ connections that are still being tested. */ -+ master_conntrack->layer7.app_proto = -+ kmalloc(strlen("unknown")+1, GFP_ATOMIC); -+ if(!master_conntrack->layer7.app_proto){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "match_no_append, bailing.\n"); -+ return 1; -+ } -+ strcpy(master_conntrack->layer7.app_proto, "unknown"); -+ return 0; -+ } -+} -+ -+/* add the new app data to the conntrack. Return number of bytes added. */ -+static int add_data(struct nf_conn * master_conntrack, -+ char * app_data, int appdatalen) -+{ -+ int length = 0, i; -+ int oldlength = master_conntrack->layer7.app_data_len; -+ -+ /* This is a fix for a race condition by Deti Fliegl. However, I'm not -+ clear on whether the race condition exists or whether this really -+ fixes it. I might just be being dense... Anyway, if it's not really -+ a fix, all it does is waste a very small amount of time. */ -+ if(!master_conntrack->layer7.app_data) return 0; -+ -+ /* Strip nulls. Make everything lower case (our regex lib doesn't -+ do case insensitivity). Add it to the end of the current data. */ -+ for(i = 0; i < maxdatalen-oldlength-1 && -+ i < appdatalen; i++) { -+ if(app_data[i] != '\0') { -+ /* the kernel version of tolower mungs 'upper ascii' */ -+ master_conntrack->layer7.app_data[length+oldlength] = -+ isascii(app_data[i])? -+ tolower(app_data[i]) : app_data[i]; -+ length++; -+ } -+ } -+ -+ master_conntrack->layer7.app_data[length+oldlength] = '\0'; -+ master_conntrack->layer7.app_data_len = length + oldlength; -+ -+ return length; -+} -+ -+/* taken from drivers/video/modedb.c */ -+static int my_atoi(const char *s) -+{ -+ int val = 0; -+ -+ for (;; s++) { -+ switch (*s) { -+ case '0'...'9': -+ val = 10*val+(*s-'0'); -+ break; -+ default: -+ return val; -+ } -+ } -+} -+ -+/* write out num_packets to userland. */ -+static int layer7_read_proc(char* page, char ** start, off_t off, int count, -+ int* eof, void * data) -+{ -+ if(num_packets > 99 && net_ratelimit()) -+ printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n"); -+ -+ page[0] = num_packets/10 + '0'; -+ page[1] = num_packets%10 + '0'; -+ page[2] = '\n'; -+ page[3] = '\0'; -+ -+ *eof=1; -+ -+ return 3; -+} -+ -+/* Read in num_packets from userland */ -+static int layer7_write_proc(struct file* file, const char* buffer, -+ unsigned long count, void *data) -+{ -+ char * foo = kmalloc(count, GFP_ATOMIC); -+ -+ if(!foo){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory, bailing. " -+ "num_packets unchanged.\n"); -+ return count; -+ } -+ -+ if(copy_from_user(foo, buffer, count)) { -+ return -EFAULT; -+ } -+ -+ -+ num_packets = my_atoi(foo); -+ kfree (foo); -+ -+ /* This has an arbitrary limit to make the math easier. I'm lazy. -+ But anyway, 99 is a LOT! If you want more, you're doing it wrong! */ -+ if(num_packets > 99) { -+ printk(KERN_WARNING "layer7: num_packets can't be > 99.\n"); -+ num_packets = 99; -+ } else if(num_packets < 1) { -+ printk(KERN_WARNING "layer7: num_packets can't be < 1.\n"); -+ num_packets = 1; -+ } -+ -+ return count; -+} -+ -+static bool -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) -+match(const struct sk_buff *skbin, struct xt_action_param *par) -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) -+match(const struct sk_buff *skbin, const struct xt_match_param *par) -+#else -+match(const struct sk_buff *skbin, -+ const struct net_device *in, -+ const struct net_device *out, -+ const struct xt_match *match, -+ const void *matchinfo, -+ int offset, -+ unsigned int protoff, -+ bool *hotdrop) -+#endif -+{ -+ /* sidestep const without getting a compiler warning... */ -+ struct sk_buff * skb = (struct sk_buff *)skbin; -+ -+ const struct xt_layer7_info * info = -+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) -+ par->matchinfo; -+ #else -+ matchinfo; -+ #endif -+ -+ enum ip_conntrack_info master_ctinfo, ctinfo; -+ struct nf_conn *master_conntrack, *conntrack; -+ unsigned char * app_data; -+ unsigned int pattern_result, appdatalen; -+ regexp * comppattern; -+ -+ /* Be paranoid/incompetent - lock the entire match function. */ -+ spin_lock_bh(&l7_lock); -+ -+ if(!can_handle(skb)){ -+ DPRINTK("layer7: This is some protocol I can't handle.\n"); -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ -+ /* Treat parent & all its children together as one connection, except -+ for the purpose of setting conntrack->layer7.app_proto in the actual -+ connection. This makes /proc/net/ip_conntrack more satisfying. */ -+ if(!(conntrack = nf_ct_get(skb, &ctinfo)) || -+ !(master_conntrack=nf_ct_get(skb,&master_ctinfo))){ -+ DPRINTK("layer7: couldn't get conntrack.\n"); -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ -+ /* Try to get a master conntrack (and its master etc) for FTP, etc. */ -+ while (master_ct(master_conntrack) != NULL) -+ master_conntrack = master_ct(master_conntrack); -+ -+ /* if we've classified it or seen too many packets */ -+ if(total_acct_packets(master_conntrack) > num_packets || -+ master_conntrack->layer7.app_proto) { -+ -+ pattern_result = match_no_append(conntrack, master_conntrack, -+ ctinfo, master_ctinfo, info); -+ -+ /* skb->cb[0] == seen. Don't do things twice if there are -+ multiple l7 rules. I'm not sure that using cb for this purpose -+ is correct, even though it says "put your private variables -+ there". But it doesn't look like it is being used for anything -+ else in the skbs that make it here. */ -+ skb->cb[0] = 1; /* marking it seen here's probably irrelevant */ -+ -+ spin_unlock_bh(&l7_lock); -+ return (pattern_result ^ info->invert); -+ } -+ -+ if(skb_is_nonlinear(skb)){ -+ if(skb_linearize(skb) != 0){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: failed to linearize " -+ "packet, bailing.\n"); -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ } -+ -+ /* now that the skb is linearized, it's safe to set these. */ -+ app_data = skb->data + app_data_offset(skb); -+ appdatalen = skb_tail_pointer(skb) - app_data; -+ -+ /* the return value gets checked later, when we're ready to use it */ -+ comppattern = compile_and_cache(info->pattern, info->protocol); -+ -+ /* On the first packet of a connection, allocate space for app data */ -+ if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] && -+ !master_conntrack->layer7.app_data){ -+ master_conntrack->layer7.app_data = -+ kmalloc(maxdatalen, GFP_ATOMIC); -+ if(!master_conntrack->layer7.app_data){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "match, bailing.\n"); -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ -+ master_conntrack->layer7.app_data[0] = '\0'; -+ } -+ -+ /* Can be here, but unallocated, if numpackets is increased near -+ the beginning of a connection */ -+ if(master_conntrack->layer7.app_data == NULL){ -+ spin_unlock_bh(&l7_lock); -+ return info->invert; /* unmatched */ -+ } -+ -+ if(!skb->cb[0]){ -+ int newbytes; -+ newbytes = add_data(master_conntrack, app_data, appdatalen); -+ -+ if(newbytes == 0) { /* didn't add any data */ -+ skb->cb[0] = 1; -+ /* Didn't match before, not going to match now */ -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ } -+ -+ /* If looking for "unknown", then never match. "Unknown" means that -+ we've given up; we're still trying with these packets. */ -+ if(!strcmp(info->protocol, "unknown")) { -+ pattern_result = 0; -+ /* If looking for "unset", then always match. "Unset" means that we -+ haven't yet classified the connection. */ -+ } else if(!strcmp(info->protocol, "unset")) { -+ pattern_result = 2; -+ DPRINTK("layer7: matched unset: not yet classified " -+ "(%d/%d packets)\n", -+ total_acct_packets(master_conntrack), num_packets); -+ /* If the regexp failed to compile, don't bother running it */ -+ } else if(comppattern && -+ regexec(comppattern, master_conntrack->layer7.app_data)){ -+ DPRINTK("layer7: matched %s\n", info->protocol); -+ pattern_result = 1; -+ } else pattern_result = 0; -+ -+ if(pattern_result == 1) { -+ master_conntrack->layer7.app_proto = -+ kmalloc(strlen(info->protocol)+1, GFP_ATOMIC); -+ if(!master_conntrack->layer7.app_proto){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "match, bailing.\n"); -+ spin_unlock_bh(&l7_lock); -+ return (pattern_result ^ info->invert); -+ } -+ strcpy(master_conntrack->layer7.app_proto, info->protocol); -+ } else if(pattern_result > 1) { /* cleanup from "unset" */ -+ pattern_result = 1; -+ } -+ -+ /* mark the packet seen */ -+ skb->cb[0] = 1; -+ -+ spin_unlock_bh(&l7_lock); -+ return (pattern_result ^ info->invert); -+} -+ -+// load nf_conntrack_ipv4 -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) -+static int -+#else -+static bool -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) -+check(const struct xt_mtchk_param *par) -+{ -+ if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { -+ printk(KERN_WARNING "can't load conntrack support for " -+ "proto=%d\n", par->match->family); -+#else -+check(const char *tablename, const void *inf, -+ const struct xt_match *match, void *matchinfo, -+ unsigned int hook_mask) -+{ -+ if (nf_ct_l3proto_try_module_get(match->family) < 0) { -+ printk(KERN_WARNING "can't load conntrack support for " -+ "proto=%d\n", match->family); -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) -+ return -EINVAL; -+ } -+ return 0; -+#else -+ return 0; -+ } -+ return 1; -+#endif -+} -+ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) -+ static void destroy(const struct xt_mtdtor_param *par) -+ { -+ nf_ct_l3proto_module_put(par->match->family); -+ } -+#else -+ static void destroy(const struct xt_match *match, void *matchinfo) -+ { -+ nf_ct_l3proto_module_put(match->family); -+ } -+#endif -+ -+static struct xt_match xt_layer7_match[] __read_mostly = { -+{ -+ .name = "layer7", -+ .family = AF_INET, -+ .checkentry = check, -+ .match = match, -+ .destroy = destroy, -+ .matchsize = sizeof(struct xt_layer7_info), -+ .me = THIS_MODULE -+} -+}; -+ -+static void layer7_cleanup_proc(void) -+{ -+ remove_proc_entry("layer7_numpackets", init_net.proc_net); -+} -+ -+/* register the proc file */ -+static void layer7_init_proc(void) -+{ -+ struct proc_dir_entry* entry; -+ entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net); -+ entry->read_proc = layer7_read_proc; -+ entry->write_proc = layer7_write_proc; -+} -+ -+static int __init xt_layer7_init(void) -+{ -+ need_conntrack(); -+ -+ if (init_net.ct.sysctl_acct == 0) { -+ printk(KERN_WARNING "layer7: enabling nf_conntrack_acct\n"); -+ init_net.ct.sysctl_acct = 1; -+ } -+ -+ layer7_init_proc(); -+ if(maxdatalen < 1) { -+ printk(KERN_WARNING "layer7: maxdatalen can't be < 1, " -+ "using 1\n"); -+ maxdatalen = 1; -+ } -+ /* This is not a hard limit. It's just here to prevent people from -+ bringing their slow machines to a grinding halt. */ -+ else if(maxdatalen > 65536) { -+ printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, " -+ "using 65536\n"); -+ maxdatalen = 65536; -+ } -+ return xt_register_matches(xt_layer7_match, -+ ARRAY_SIZE(xt_layer7_match)); -+} -+ -+static void __exit xt_layer7_fini(void) -+{ -+ layer7_cleanup_proc(); -+ xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match)); -+} -+ -+module_init(xt_layer7_init); -+module_exit(xt_layer7_fini); diff --git a/src/patches/openssl-0.9.8n-cryptodev.diff b/src/patches/openssl-0.9.8n-cryptodev.diff deleted file mode 100644 index 0913f9a..0000000 --- a/src/patches/openssl-0.9.8n-cryptodev.diff +++ /dev/null @@ -1,99 +0,0 @@ -diff -Naur openssl-0.9.8n.org/crypto/engine/eng_all.c openssl-0.9.8n/crypto/engine/eng_all.c ---- openssl-0.9.8n.org/crypto/engine/eng_all.c 2010-03-01 01:30:11.000000000 +0100 -+++ openssl-0.9.8n/crypto/engine/eng_all.c 2010-03-30 08:11:26.000000000 +0200 -@@ -104,16 +104,13 @@ - #endif - #endif - #ifndef OPENSSL_NO_HW --#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) - ENGINE_load_cryptodev(); --#endif - #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) - ENGINE_load_capi(); - #endif - #endif - } - --#if defined(__OpenBSD__) || defined(__FreeBSD__) - void ENGINE_setup_bsd_cryptodev(void) { - static int bsd_cryptodev_default_loaded = 0; - if (!bsd_cryptodev_default_loaded) { -@@ -122,4 +119,3 @@ - } - bsd_cryptodev_default_loaded=1; - } --#endif -diff -Naur openssl-0.9.8n.org/crypto/engine/eng_cryptodev.c openssl-0.9.8n/crypto/engine/eng_cryptodev.c ---- openssl-0.9.8n.org/crypto/engine/eng_cryptodev.c 2010-03-03 16:30:05.000000000 +0100 -+++ openssl-0.9.8n/crypto/engine/eng_cryptodev.c 2010-03-30 08:01:11.000000000 +0200 -@@ -38,14 +38,15 @@ - #if (defined(__unix__) || defined(unix)) && !defined(USG) && \ - (defined(OpenBSD) || defined(__FreeBSD__)) - #include <sys/param.h> --# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) --# define HAVE_CRYPTODEV --# endif - # if (OpenBSD >= 200110) - # define HAVE_SYSLOG_R - # endif - #endif - -+#if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) || defined(__linux__) -+# define HAVE_CRYPTODEV -+#endif -+ - #ifndef HAVE_CRYPTODEV - - void -@@ -58,7 +59,12 @@ - #else - - #include <sys/types.h> --#include <crypto/cryptodev.h> -+#if defined(__linux__) -+# include <linux/cryptodev.h> -+# define HAVE_CRYPTODEV_NAME -+#else -+# include <crypto/cryptodev.h> -+#endif - #include <sys/ioctl.h> - #include <errno.h> - #include <stdio.h> -@@ -81,7 +87,11 @@ - static int get_dev_crypto(void); - static int cryptodev_max_iv(int cipher); - static int cryptodev_key_length_valid(int cipher, int len); --static int cipher_nid_to_cryptodev(int nid); -+#ifndef HAVE_CRYPTODEV_NAME -+ static int cipher_nid_to_cryptodev(int nid); -+#else -+ static char *cipher_nid_to_cryptodev_name(int nid); -+#endif - static int get_cryptodev_ciphers(const int **cnids); - /*static int get_cryptodev_digests(const int **cnids);*/ - static int cryptodev_usable_ciphers(const int **nids); -diff -Naur openssl-0.9.8n.org/crypto/engine/engine.h openssl-0.9.8n/crypto/engine/engine.h ---- openssl-0.9.8n.org/crypto/engine/engine.h 2010-02-09 15:18:15.000000000 +0100 -+++ openssl-0.9.8n/crypto/engine/engine.h 2010-03-30 08:01:11.000000000 +0200 -@@ -705,9 +705,7 @@ - * values. */ - void *ENGINE_get_static_state(void); - --#if defined(__OpenBSD__) || defined(__FreeBSD__) - void ENGINE_setup_bsd_cryptodev(void); --#endif - - /* BEGIN ERROR CODES */ - /* The following lines are auto generated by the script mkerr.pl. Any changes -diff -Naur openssl-0.9.8n.org/crypto/evp/c_all.c openssl-0.9.8n/crypto/evp/c_all.c ---- openssl-0.9.8n.org/crypto/evp/c_all.c 2004-08-29 18:36:04.000000000 +0200 -+++ openssl-0.9.8n/crypto/evp/c_all.c 2010-03-30 08:01:11.000000000 +0200 -@@ -83,8 +83,6 @@ - OpenSSL_add_all_ciphers(); - OpenSSL_add_all_digests(); - #ifndef OPENSSL_NO_ENGINE --# if defined(__OpenBSD__) || defined(__FreeBSD__) - ENGINE_setup_bsd_cryptodev(); --# endif - #endif - } diff --git a/src/patches/pciutils-2.1.10-scan.patch b/src/patches/pciutils-2.1.10-scan.patch deleted file mode 100644 index 590c21d..0000000 --- a/src/patches/pciutils-2.1.10-scan.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- pciutils-2.1.10/lib/access.c.foo Wed Feb 12 15:44:05 2003 -+++ pciutils-2.1.10/lib/access.c Wed Feb 12 15:44:33 2003 -@@ -180,7 +180,8 @@ - void - pci_scan_bus(struct pci_access *a) - { -- a->methods->scan(a); -+ if (a->methods) -+ a->methods->scan(a); - } - - struct pci_dev * diff --git a/src/patches/pciutils-2.1.99-gcc4.patch b/src/patches/pciutils-2.1.99-gcc4.patch deleted file mode 100644 index 43257d5..0000000 --- a/src/patches/pciutils-2.1.99-gcc4.patch +++ /dev/null @@ -1,17 +0,0 @@ -Patch by Robert Scheck redhat@linuxnetz.de for pciutils >= 2.1.99, which make pciutils -rebuildable using gcc 4. - ---- pciutils-2.1.99-test8/lib/i386-ports.c 2004-08-13 22:13:11.000000000 +0200 -+++ pciutils-2.1.99-test8/lib/i386-ports.c.gcc4 2005-03-14 09:30:06.000000000 +0100 -@@ -57,9 +57,9 @@ - for(d.dev = 0; d.dev < 32; d.dev++) - { - u16 class, vendor; -- if (m->read(&d, PCI_CLASS_DEVICE, (byte *) &class, sizeof(class)) && -+ if ((m->read) (&d, PCI_CLASS_DEVICE, (byte *) &class, sizeof(class)) && - (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST) || class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)) || -- m->read(&d, PCI_VENDOR_ID, (byte *) &vendor, sizeof(vendor)) && -+ (m->read) (&d, PCI_VENDOR_ID, (byte *) &vendor, sizeof(vendor)) && - (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL) || vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ))) - { - a->debug("...outside the Asylum at 0/%02x/0", d.dev); diff --git a/src/patches/pciutils-2.2.1-idpath.patch b/src/patches/pciutils-2.2.1-idpath.patch deleted file mode 100644 index 62b57f0..0000000 --- a/src/patches/pciutils-2.2.1-idpath.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- pciutils-2.2.1/Makefile.idpath 2006-02-23 12:24:12.000000000 +0100 -+++ pciutils-2.2.1/Makefile 2006-02-23 12:24:18.000000000 +0100 -@@ -10,7 +10,7 @@ - PREFIX=/usr/local - SBINDIR=$(PREFIX)/sbin - SHAREDIR=$(PREFIX)/share --IDSDIR=$(SHAREDIR) -+IDSDIR=$(SHAREDIR)/hwdata - MANDIR:=$(shell if [ -d $(PREFIX)/share/man ] ; then echo $(PREFIX)/share/man ; else echo $(PREFIX)/man ; fi) - INSTALL=install - DIRINSTALL=install -d diff --git a/src/patches/pciutils-2.2.3-multilib.patch b/src/patches/pciutils-2.2.3-multilib.patch deleted file mode 100644 index 789dee5..0000000 --- a/src/patches/pciutils-2.2.3-multilib.patch +++ /dev/null @@ -1,130 +0,0 @@ ---- pciutils-2.2.3/lib/configure.multilib 2006-05-05 14:25:07.000000000 +0200 -+++ pciutils-2.2.3/lib/configure 2006-05-23 15:50:16.000000000 +0200 -@@ -30,8 +30,37 @@ - echo " $host $rel" - - c=config.h --echo >$c "#define PCI_ARCH_`echo $cpu | tr 'a-z' 'A-Z'`" --echo >>$c "#define PCI_OS_`echo $sys | tr 'a-z' 'A-Z'`" -+cm=config.h.mk -+cat >$c <<EOF -+#if defined(__x86_64__) -+#define PCI_ARCH_X86_64 -+#elif defined(__ia64__) -+#define PCI_ARCH_IA64 -+#elif defined(__i386__) -+#define PCI_ARCH_I386 -+#define PCI_HAVE_PM_INTEL_CONF -+#elif defined(__ppc64__) || defined(__powerpc64__) -+#define PCI_ARCH_PPC64 -+#elif defined(__ppc__) || defined(__powerpc__) -+#define PCI_ARCH_PPC -+#elif defined(__s390x__) -+#define PCI_ARCH_S390X -+#elif defined(__s390__) -+#define PCI_ARCH_S390 -+#else -+#error Unknown Arch -+#endif -+#define PCI_OS_LINUX -+#define PCI_HAVE_PM_LINUX_SYSFS -+#define PCI_HAVE_PM_LINUX_PROC -+#define PCI_HAVE_LINUX_BYTEORDER_H -+#define PCI_PATH_PROC_BUS_PCI "/proc/bus/pci" -+#define PCI_PATH_SYS_BUS_PCI "/sys/bus/pci" -+#define PCI_HAVE_64BIT_ADDRESS -+EOF -+ -+echo >$cm "#define PCI_ARCH_`echo $cpu | tr 'a-z' 'A-Z'`" -+echo >>$cm "#define PCI_OS_`echo $sys | tr 'a-z' 'A-Z'`" - - echo_n "Looking for access methods..." - -@@ -39,63 +68,22 @@ - linux*) - case $rel in - 2.[1-9]*|[3-9]*) echo_n " sysfs proc" -- echo >>$c '#define PCI_HAVE_PM_LINUX_SYSFS' -- echo >>$c '#define PCI_HAVE_PM_LINUX_PROC' -- echo >>$c '#define PCI_HAVE_LINUX_BYTEORDER_H' -- echo >>$c '#define PCI_PATH_PROC_BUS_PCI "/proc/bus/pci"' -- echo >>$c '#define PCI_PATH_SYS_BUS_PCI "/sys/bus/pci"' -- ok=1 -- ;; -- esac -- case $cpu in -- i386) echo_n " i386-ports" -- echo >>$c '#define PCI_HAVE_PM_INTEL_CONF' -+ echo >>$cm '#define PCI_HAVE_PM_LINUX_SYSFS' -+ echo >>$cm '#define PCI_HAVE_PM_LINUX_PROC' -+ echo >>$cm '#define PCI_HAVE_LINUX_BYTEORDER_H' -+ echo >>$cm '#define PCI_PATH_PROC_BUS_PCI "/proc/bus/pci"' -+ echo >>$cm '#define PCI_PATH_SYS_BUS_PCI "/sys/bus/pci"' - ok=1 - ;; - esac -- echo >>$c '#define PCI_HAVE_64BIT_ADDRESS' -- ;; -- sunos) - case $cpu in - i386) echo_n " i386-ports" -- echo >>$c "#define PCI_HAVE_PM_INTEL_CONF" -+ echo >>$cm '#define PCI_HAVE_PM_INTEL_CONF' - ok=1 - ;; -- *) -- echo " The PCI library is does not support Solaris for this architecture: $cpu" -- exit 1 -- ;; - esac -- ;; -- -- freebsd) -- echo_n " fbsd-device" -- echo >>$c '#define PCI_HAVE_PM_FBSD_DEVICE' -- echo >>$c '#define PCI_PATH_FBSD_DEVICE "/dev/pci"' -- ok=1 -- ;; -- openbsd) -- echo_n " obsd-device" -- echo >>$c '#define PCI_HAVE_PM_OBSD_DEVICE' -- echo >>$c '#define PCI_PATH_OBSD_DEVICE "/dev/pci"' -- ok=1 -- ;; -- aix) -- echo_n " aix-device" -- echo >>$c '#define PCI_HAVE_PM_AIX_DEVICE' -- ok=1 -- ;; -- netbsd) -- echo_n " nbsd-libpci" -- echo >>$c '#define PCI_HAVE_PM_NBSD_LIBPCI' -- echo >>$c '#define PCI_PATH_NBSD_DEVICE "/dev/pci0"' -- ok=1 -- ;; -- gnu) -- echo_n " i386-ports" -- echo >>$c '#define PCI_HAVE_PM_INTEL_CONF' -- ok=1 -- ;; -+ echo >>$cm '#define PCI_HAVE_64BIT_ADDRESS' -+ ;; - *) - echo " Unfortunately, your OS is not supported by the PCI Library" - exit 1 -@@ -103,10 +91,14 @@ - esac - - echo >>$c '#define PCI_HAVE_PM_DUMP' -+echo >>$cm '#define PCI_HAVE_PM_DUMP' - echo " dump" - if [ -z "$ok" ] ; then - echo "WARNING: No real configuration access method is available." - fi - echo >>$c "#define PCI_PATH_IDS "$idsdir/pci.ids"" - echo >>$c "#define PCILIB_VERSION "$version"" --sed '/^#define [^ ]*$/!d;s/^#define (.*)/\1=1/' <$c >config.mk -+ -+echo >>$cm "#define PCI_PATH_IDS "$idsdir/pci.ids"" -+echo >>$cm "#define PCILIB_VERSION "$version"" -+sed '/^#define [^ ]*$/!d;s/^#define (.*)/\1=1/' <$cm >config.mk diff --git a/src/patches/pciutils-2.2.3-sata.patch b/src/patches/pciutils-2.2.3-sata.patch deleted file mode 100644 index 14f9f5e..0000000 --- a/src/patches/pciutils-2.2.3-sata.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- pciutils-2.2.3/lib/header.h.sata 2006-08-09 13:16:07.000000000 -0400 -+++ pciutils-2.2.3/lib/header.h 2006-08-09 13:17:45.000000000 -0400 -@@ -855,6 +855,8 @@ - #define PCI_CLASS_STORAGE_FLOPPY 0x0102 - #define PCI_CLASS_STORAGE_IPI 0x0103 - #define PCI_CLASS_STORAGE_RAID 0x0104 -+#define PCI_CLASS_STORAGE_ATA 0x0105 -+#define PCI_CLASS_STORAGE_SATA 0x0106 - #define PCI_CLASS_STORAGE_OTHER 0x0180 - - #define PCI_BASE_CLASS_NETWORK 0x02 diff --git a/src/patches/pciutils-devicetype.patch b/src/patches/pciutils-devicetype.patch deleted file mode 100644 index 87e45b4..0000000 --- a/src/patches/pciutils-devicetype.patch +++ /dev/null @@ -1,136 +0,0 @@ ---- pciutils-2.2.1/lib/sysfs.c.devicetype 2005-09-21 07:51:00.000000000 -0400 -+++ pciutils-2.2.1/lib/sysfs.c 2005-12-13 17:02:12.000000000 -0500 -@@ -164,7 +164,6 @@ - sysfs_get_resources(d); - d->irq = sysfs_get_value(d, "irq"); - d->known_fields = PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES; --#if 0 - /* - * We prefer reading these from the config registers, it's faster. - * However, it would be possible and maybe even useful to hack the kernel -@@ -173,8 +172,8 @@ - */ - d->vendor_id = sysfs_get_value(d, "vendor"); - d->device_id = sysfs_get_value(d, "device"); -- d->known_fields |= PCI_FILL_IDENT; --#endif -+ d->device_class = sysfs_get_value(d, "class") >> 8; -+ d->known_fields |= PCI_FILL_IDENT | PCI_FILL_CLASS; - } - pci_link_dev(a, d); - } ---- pciutils-2.2.1/lib/pci.h.devicetype 2005-09-10 08:10:54.000000000 -0400 -+++ pciutils-2.2.1/lib/pci.h 2005-12-13 17:02:12.000000000 -0500 -@@ -84,6 +84,7 @@ - /* These fields are set by pci_fill_info() */ - int known_fields; /* Set of info fields already known */ - u16 vendor_id, device_id; /* Identity of the device */ -+ u16 device_class; /* PCI device class */ - int irq; /* IRQ number */ - pciaddr_t base_addr[6]; /* Base addresses */ - pciaddr_t size[6]; /* Region sizes */ -@@ -118,6 +119,7 @@ - #define PCI_FILL_BASES 4 - #define PCI_FILL_ROM_BASE 8 - #define PCI_FILL_SIZES 16 -+#define PCI_FILL_CLASS 32 - #define PCI_FILL_RESCAN 0x10000 - - void pci_setup_cache(struct pci_dev *, u8 *cache, int len); ---- pciutils-2.2.1/lib/generic.c.devicetype 2004-08-13 16:15:23.000000000 -0400 -+++ pciutils-2.2.1/lib/generic.c 2005-12-13 17:02:12.000000000 -0500 -@@ -46,7 +46,8 @@ - d->func = t->func; - d->vendor_id = vd & 0xffff; - d->device_id = vd >> 16U; -- d->known_fields = PCI_FILL_IDENT; -+ d->device_class = pci_read_byte(t,PCI_CLASS_DEVICE+1) << 8 | pci_read_byte(t, PCI_CLASS_DEVICE); -+ d->known_fields = PCI_FILL_IDENT | PCI_FILL_CLASS; - d->hdrtype = ht; - pci_link_dev(a, d); - switch (ht) -@@ -86,6 +87,8 @@ - d->vendor_id = pci_read_word(d, PCI_VENDOR_ID); - d->device_id = pci_read_word(d, PCI_DEVICE_ID); - } -+ if (flags & PCI_FILL_CLASS) -+ d->device_class = pci_read_byte(d, PCI_CLASS_DEVICE+1) << 8 | pci_read_byte(d, PCI_CLASS_DEVICE); - if (flags & PCI_FILL_IRQ) - d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE); - if (flags & PCI_FILL_BASES) ---- pciutils-2.2.1/lib/example.c.devicetype 2000-03-09 03:38:33.000000000 -0500 -+++ pciutils-2.2.1/lib/example.c 2005-12-13 17:02:12.000000000 -0500 -@@ -21,7 +21,7 @@ - pci_scan_bus(pacc); /* We want to get the list of devices */ - for(dev=pacc->devices; dev; dev=dev->next) /* Iterate over all devices */ - { -- pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES); /* Fill in header info we need */ -+ pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); /* Fill in header info we need */ - c = pci_read_word(dev, PCI_CLASS_DEVICE); /* Read config register directly */ - printf("%02x:%02x.%d vendor=%04x device=%04x class=%04x irq=%d base0=%lx\n", - dev->bus, dev->dev, dev->func, dev->vendor_id, dev->device_id, ---- pciutils-2.2.1/lspci.c.devicetype 2005-11-26 06:48:29.000000000 -0500 -+++ pciutils-2.2.1/lspci.c 2005-12-13 17:04:39.000000000 -0500 -@@ -123,7 +123,7 @@ - d->config_cached += 64; - } - pci_setup_cache(p, d->config, d->config_cached); -- pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES); -+ pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES); - return d; - } - -@@ -255,7 +255,7 @@ - printf(" %s: %s", - pci_lookup_name(pacc, classbuf, sizeof(classbuf), - PCI_LOOKUP_CLASS, -- get_conf_word(d, PCI_CLASS_DEVICE)), -+ p->device_class), - pci_lookup_name(pacc, devbuf, sizeof(devbuf), - PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE, - p->vendor_id, p->device_id)); -@@ -267,7 +267,7 @@ - c = get_conf_byte(d, PCI_CLASS_PROG); - x = pci_lookup_name(pacc, devbuf, sizeof(devbuf), - PCI_LOOKUP_PROGIF | PCI_LOOKUP_NO_NUMBERS, -- get_conf_word(d, PCI_CLASS_DEVICE), c); -+ p->device_class, c); - if (c || x) - { - printf(" (prog-if %02x", c); -@@ -1585,7 +1585,7 @@ - struct pci_dev *p = d->dev; - word status = get_conf_word(d, PCI_STATUS); - word cmd = get_conf_word(d, PCI_COMMAND); -- word class = get_conf_word(d, PCI_CLASS_DEVICE); -+ word class = p->device_class; - byte bist = get_conf_byte(d, PCI_BIST); - byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f; - byte latency = get_conf_byte(d, PCI_LATENCY_TIMER); -@@ -1783,7 +1783,7 @@ - show_slot_name(d); - putchar('\n'); - printf("Class:\t%s\n", -- pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, get_conf_word(d, PCI_CLASS_DEVICE))); -+ pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, p->device_class)); - printf("Vendor:\t%s\n", - pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id)); - printf("Device:\t%s\n", -@@ -1805,7 +1805,7 @@ - show_slot_name(d); - printf(" "%s" "%s" "%s"", - pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, -- get_conf_word(d, PCI_CLASS_DEVICE)), -+ p->device_class), - pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, - p->vendor_id, p->device_id), - pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_DEVICE, -@@ -1929,7 +1929,7 @@ - last_br = &host_bridge.chain; - for(d=first_dev; d; d=d->next) - { -- word class = get_conf_word(d, PCI_CLASS_DEVICE); -+ word class = d->dev->device_class; - byte ht = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f; - if (class == PCI_CLASS_BRIDGE_PCI && - (ht == PCI_HEADER_TYPE_BRIDGE || ht == PCI_HEADER_TYPE_CARDBUS)) diff --git a/src/patches/pciutils-havepread.patch b/src/patches/pciutils-havepread.patch deleted file mode 100644 index 56fbff3..0000000 --- a/src/patches/pciutils-havepread.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- pciutils-2.1.99-test8/lib/pread.h.pread 2004-08-13 16:15:46.000000000 -0400 -+++ pciutils-2.1.99-test8/lib/pread.h 2004-08-31 00:30:03.168157294 -0400 -@@ -12,54 +12,6 @@ - * don't define it. - */ - --#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0 --/* glibc 2.1 or newer -> pread/pwrite supported automatically */ -- --#elif defined(i386) && defined(__GLIBC__) --/* glibc 2.0 on i386 -> call syscalls directly */ --#include <asm/unistd.h> --#include <syscall-list.h> --#ifndef SYS_pread --#define SYS_pread 180 --#endif --static int pread(unsigned int fd, void *buf, size_t size, loff_t where) --{ return syscall(SYS_pread, fd, buf, size, where); } --#ifndef SYS_pwrite --#define SYS_pwrite 181 --#endif --static int pwrite(unsigned int fd, void *buf, size_t size, loff_t where) --{ return syscall(SYS_pwrite, fd, buf, size, where); } -- --#elif defined(i386) --/* old libc on i386 -> call syscalls directly the old way */ --#include <asm/unistd.h> --static _syscall5(int, pread, unsigned int, fd, void *, buf, size_t, size, u32, where_lo, u32, where_hi); --static _syscall5(int, pwrite, unsigned int, fd, void *, buf, size_t, size, u32, where_lo, u32, where_hi); --static int do_read(struct pci_dev *d UNUSED, int fd, void *buf, size_t size, int where) { return pread(fd, buf, size, where, 0); } --static int do_write(struct pci_dev *d UNUSED, int fd, void *buf, size_t size, int where) { return pwrite(fd, buf, size, where, 0); } --#define PCI_HAVE_DO_READ -- --#else --/* In all other cases we use lseek/read/write instead to be safe */ --#define make_rw_glue(op) \ -- static int do_##op(struct pci_dev *d, int fd, void *buf, size_t size, int where) \ -- { \ -- struct pci_access *a = d->access; \ -- int r; \ -- if (a->fd_pos != where && lseek(fd, where, SEEK_SET) < 0) \ -- return -1; \ -- r = op(fd, buf, size); \ -- if (r < 0) \ -- a->fd_pos = -1; \ -- else \ -- a->fd_pos = where + r; \ -- return r; \ -- } --make_rw_glue(read) --make_rw_glue(write) --#define PCI_HAVE_DO_READ --#endif -- - #ifndef PCI_HAVE_DO_READ - #define do_read(d,f,b,l,p) pread(f,b,l,p) - #define do_write(d,f,b,l,p) pwrite(f,b,l,p) diff --git a/src/patches/pciutils-strip.patch b/src/patches/pciutils-strip.patch deleted file mode 100644 index 19ca22e..0000000 --- a/src/patches/pciutils-strip.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- pciutils-2.1.99-test3/Makefile.strip 2004-02-25 01:46:14.315787866 -0500 -+++ pciutils-2.1.99-test3/Makefile 2004-02-25 01:47:45.478046260 -0500 -@@ -32,7 +32,7 @@ - all: $(PCILIB) lspci setpci lspci.8 setpci.8 update-pciids update-pciids.8 pci.ids - - $(PCILIB): $(PCIINC) force -- $(MAKE) -C lib all -+ CFLAGS="$(CFLAGS) -fPIC" $(MAKE) -C lib all - - force: - ---- pciutils-2.1.99-test8/Makefile.foo 2005-05-10 15:24:45.000000000 -0400 -+++ pciutils-2.1.99-test8/Makefile 2005-05-10 15:24:50.000000000 -0400 -@@ -65,7 +65,7 @@ - install: all - # -c is ignored on Linux, but required on FreeBSD - $(DIRINSTALL) -m 755 $(SBINDIR) $(IDSDIR) $(MANDIR)/man8 -- $(INSTALL) -c -m 755 -s lspci setpci $(SBINDIR) -+ $(INSTALL) -c -m 755 lspci setpci $(SBINDIR) - $(INSTALL) -c -m 755 update-pciids $(SBINDIR) - $(INSTALL) -c -m 644 pci.ids $(IDSDIR) - $(INSTALL) -c -m 644 lspci.8 setpci.8 update-pciids.8 $(MANDIR)/man8 diff --git a/src/patches/pound-2.6.patch b/src/patches/pound-2.6.patch deleted file mode 100644 index 9dceebc..0000000 --- a/src/patches/pound-2.6.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- build/usr/src/Pound-2.6/configure_orig 2011-12-28 14:57:45.000000000 +0100 -+++ build/usr/src/Pound-2.6/configure 2012-02-10 21:09:50.000000000 +0100 -@@ -3232,7 +3232,7 @@ - - if test "${CC}" = "gcc" - then -- CPPFLAGS="${CPPFLAGS} -Wstrict-prototypes -Wno-unused-result -pipe" -+ CPPFLAGS="${CPPFLAGS} -Wstrict-prototypes -pipe" - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: *** Checking for threads library and/or flags ***" >&5 diff --git a/src/patches/python-satsolver-only-python-bindings.patch b/src/patches/python-satsolver-only-python-bindings.patch deleted file mode 100644 index 36905d0..0000000 --- a/src/patches/python-satsolver-only-python-bindings.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff -Nur old/bindings/CMakeLists.txt new/bindings/CMakeLists.txt ---- old/bindings/CMakeLists.txt 2011-04-11 22:51:37.891109001 +0200 -+++ new/bindings/CMakeLists.txt 2011-04-11 22:55:52.859108992 +0200 -@@ -21,17 +21,17 @@ - #FIND_PACKAGE(PerlLibs) - FIND_PACKAGE(Perl) - --IF (RUBY_LIBRARY AND RUBY_INCLUDE_PATH) -- ADD_SUBDIRECTORY(ruby) --ENDIF(RUBY_LIBRARY AND RUBY_INCLUDE_PATH) -+#IF (RUBY_LIBRARY AND RUBY_INCLUDE_PATH) -+# ADD_SUBDIRECTORY(ruby) -+#ENDIF(RUBY_LIBRARY AND RUBY_INCLUDE_PATH) - - IF (PYTHON_LIBRARY) - ADD_SUBDIRECTORY(python) - ENDIF(PYTHON_LIBRARY) - --IF (PERL_EXECUTABLE) -- ADD_SUBDIRECTORY(perl) --ENDIF (PERL_EXECUTABLE) -+#IF (PERL_EXECUTABLE) -+# ADD_SUBDIRECTORY(perl) -+#ENDIF (PERL_EXECUTABLE) - - SET(bindings_devel_dir "${CMAKE_CURRENT_BINARY_DIR}/satsolver-bindings") - ADD_CUSTOM_COMMAND ( diff --git a/src/patches/python-satsover-fix-building-without-rpm.patch b/src/patches/python-satsover-fix-building-without-rpm.patch deleted file mode 100644 index 68e2767..0000000 --- a/src/patches/python-satsover-fix-building-without-rpm.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -Nur src/bindings/pool.i sat-solver-bindings/bindings/pool.i ---- src/bindings/pool.i 2011-04-25 12:03:31.000000000 +0000 -+++ sat-solver-bindings/bindings/pool.i 2011-04-29 18:40:59.645929695 +0000 -@@ -474,6 +474,7 @@ - return repo; - } - -+#if defined(FEDORA) - /* - * Add RPM database to Pool. - * -@@ -493,6 +494,7 @@ - repo_add_rpmdb( repo, NULL, rootdir, 0 ); - return repo; - } -+#endif - - %newobject create_repo; - /* -diff -Nur src/bindings/repo.i sat-solver-bindings/bindings/repo.i ---- src/bindings/repo.i 2011-04-25 12:03:31.000000000 +0000 -+++ sat-solver-bindings/bindings/repo.i 2011-04-29 18:37:13.856570319 +0000 -@@ -139,11 +139,13 @@ - } - } - -+#if defined(FEDORA) - /* - * Add RPM database, optionally passing a _root_ directory - */ - void add_rpmdb( const char *rootdir ) - { repo_add_rpmdb( $self, NULL, rootdir, 0); } -+#endif - - /* - * Create solvable with +name+ and +evr+ in the Repo - diff --git a/src/patches/qemu-0.14.1_missing_ATFCWD_hack.patch b/src/patches/qemu-0.14.1_missing_ATFCWD_hack.patch deleted file mode 100644 index 31dde45..0000000 --- a/src/patches/qemu-0.14.1_missing_ATFCWD_hack.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff -Naur qemu-0.14.1.org/hw/virtio-9p-local.c qemu-0.14.1/hw/virtio-9p-local.c ---- qemu-0.14.1.org/hw/virtio-9p-local.c 2011-05-06 21:01:43.000000000 +0200 -+++ qemu-0.14.1/hw/virtio-9p-local.c 2011-05-18 14:04:32.432444320 +0200 -@@ -10,6 +10,7 @@ - * the COPYING file in the top-level directory. - * - */ -+ - #include "virtio.h" - #include "virtio-9p.h" - #include "virtio-9p-xattr.h" -@@ -20,6 +21,16 @@ - #include <sys/un.h> - #include <attr/xattr.h> - -+#ifndef AT_FDCWD -+/* Copied from linux/include/linux/fcntl.h * because direct include fails */ -+#define AT_FDCWD -100 /* Special value used to indicate -+ openat should use the current -+ working directory. */ -+#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */ -+#define AT_REMOVEDIR 0x200 /* Remove directory instead of -+ unlinking file. */ -+#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */ -+#endif - - static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf) - { diff --git a/src/patches/r8101_add_missing_pciids.patch b/src/patches/r8101_add_missing_pciids.patch deleted file mode 100644 index a065493..0000000 --- a/src/patches/r8101_add_missing_pciids.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -Naur r8101-1.013.00.org/src/r8101_n.c r8101-1.013.00/src/r8101_n.c ---- r8101-1.013.00.org/src/r8101_n.c 2009-07-14 09:10:53.000000000 +0200 -+++ r8101-1.013.00/src/r8101_n.c 2009-10-22 18:19:07.000000000 +0200 -@@ -103,6 +103,7 @@ - - static struct pci_device_id rtl8101_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), }, -+ { 0x0001, 0x8168, PCI_ANY_ID, 0x2410, }, - {0,}, - }; - diff --git a/src/patches/r8169_add_missing_pciids.patch b/src/patches/r8169_add_missing_pciids.patch deleted file mode 100644 index 86916f6..0000000 --- a/src/patches/r8169_add_missing_pciids.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff -Naur r8169-6.017.00.org/src/r8169_n.c r8169-6.017.00/src/r8169_n.c ---- r8169-6.017.00.org/src/r8169_n.c 2012-05-03 14:23:12.000000000 +0200 -+++ r8169-6.017.00/src/r8169_n.c 2012-10-14 12:43:52.478555777 +0200 -@@ -115,7 +115,12 @@ - static struct pci_device_id rtl8169_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 }, - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, -- { PCI_VENDOR_ID_DLINK, 0x4300, PCI_VENDOR_ID_DLINK, 0x4c00, 0, 0, RTL_CFG_0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, -+ { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xC107), 0, 0, RTL_CFG_0 }, -+ { PCI_DEVICE(0x16EC, 0x0116), 0, 0, RTL_CFG_0 }, -+ { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, - {0,}, - }; - diff --git a/src/patches/sudo-1.6.8p12-envvar_fix-1.patch b/src/patches/sudo-1.6.8p12-envvar_fix-1.patch deleted file mode 100644 index 5bb4db2..0000000 --- a/src/patches/sudo-1.6.8p12-envvar_fix-1.patch +++ /dev/null @@ -1,59 +0,0 @@ -Submitted By: Archaic (archaic -aT- linuxfromscratch -DoT- org) -Date: 2005-01-17 -Initial Package Version: 1.6.8p12 -Origin: Upstream CVS -Upstream Status: In CVS -Description: (CVE-2005-4158) Sudo before 1.6.8 p12, when the Perl taint flag is - off, does not clear the PERLLIB, PERL5LIB, and PERL5OPT environment - variables, which allows limited local users to cause a Perl script - to include and execute arbitrary library files that have the same - name as library files that are included by the script. - Additionally, more variables beyond perl were added to the - blacklist and comments were added to the variables. - -diff -Naur sudo-1.6.8p12.orig/env.c sudo-1.6.8p12/env.c ---- sudo-1.6.8p12.orig/env.c 2005-11-08 18:21:33.000000000 +0000 -+++ sudo-1.6.8p12/env.c 2006-01-18 00:35:17.000000000 +0000 -@@ -118,18 +118,31 @@ - "USR_ACE", - "DLC_ACE", - #endif /* HAVE_SECURID */ -- "TERMINFO", -- "TERMINFO_DIRS", -- "TERMPATH", -+ "TERMINFO", /* terminfo, exclusive path to terminfo files */ -+ "TERMINFO_DIRS", /* terminfo, path(s) to terminfo files */ -+ "TERMPATH", /* termcap, path(s) to termcap files */ - "TERMCAP", /* XXX - only if it starts with '/' */ -- "ENV", -- "BASH_ENV", -- "PS4", -- "SHELLOPTS", -- "JAVA_TOOL_OPTIONS", -- "PERLLIB", -- "PERL5LIB", -- "PERL5OPT", -+ "ENV", /* ksh, file to source before script runs */ -+ "BASH_ENV", /* bash, file to source before script runs */ -+ "PS4", /* bash, prefix for lines in xtrace mode */ -+ "GLOBIGNORE", /* bash, globbing patterns to ignore */ -+ "SHELLOPTS", /* bash, extra command line options */ -+ "JAVA_TOOL_OPTIONS", /* java, extra command line options */ -+ "PERLIO_DEBUG ", /* perl, debugging output file */ -+ "PERLLIB", /* perl, search path for modules/includes */ -+ "PERL5LIB", /* perl 5, search path for modules/includes */ -+ "PERL5OPT", /* perl 5, extra command line options */ -+ "PERL5DB", /* perl 5, command used to load debugger */ -+ "FPATH", /* ksh, search path for functions */ -+ "NULLCMD", /* zsh, command for null file redirection */ -+ "READNULLCMD", /* zsh, command for null file redirection */ -+ "ZDOTDIR", /* zsh, search path for dot files */ -+ "TMPPREFIX", /* zsh, prefix for temporary files */ -+ "PYTHONHOME", /* python, module search path */ -+ "PYTHONPATH", /* python, search path */ -+ "PYTHONINSPEC", /* python, allow inspection */ -+ "RUBYLIB", /* ruby, library load path */ -+ "RUBYOPT", /* ruby, extra command line options */ - NULL - }; - diff --git a/src/patches/udev-125-ext4_wo_journal.patch b/src/patches/udev-125-ext4_wo_journal.patch deleted file mode 100644 index 77072ce..0000000 --- a/src/patches/udev-125-ext4_wo_journal.patch +++ /dev/null @@ -1,50 +0,0 @@ -diff -Naur udev-125.org/extras/volume_id/lib/ext.c udev-125/extras/volume_id/lib/ext.c ---- udev-125.org/extras/volume_id/lib/ext.c 2008-07-18 16:26:55.000000000 +0200 -+++ udev-125/extras/volume_id/lib/ext.c 2012-06-25 00:52:40.976563010 +0200 -@@ -160,32 +160,31 @@ - goto found; - } - -- /* has journal */ -- if ((feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { -- /* "use on development code" is ext4dev */ -- if ((flags & EXT2_FLAGS_TEST_FILESYS) != 0) { -- id->type = "ext4dev"; -- goto found; -- } -+ /* "use on development code" is ext4dev */ -+ if ((flags & EXT2_FLAGS_TEST_FILESYS) != 0) { -+ id->type = "ext4dev"; -+ goto found; -+ } - -- /* incompatible ext3 features is ext4 */ -- if ((feature_ro_compat & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) != 0 || -- (feature_incompat & EXT3_FEATURE_INCOMPAT_UNSUPPORTED) != 0) { -- id->type = "ext4"; -- goto found; -- } -+ /* incompatible ext3 features is ext4 */ -+ if ((feature_ro_compat & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) != 0 || -+ (feature_incompat & EXT3_FEATURE_INCOMPAT_UNSUPPORTED) != 0) { -+ id->type = "ext4"; -+ goto found; -+ } - -+ /* has journal */ -+ if ((feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { - id->type = "ext3"; - goto found; - } else { -- /* no incompatible ext2 feature is ext2 */ -+ /* no incompatible ext2 feature is ext2 */ - if ((feature_ro_compat & EXT2_FEATURE_RO_COMPAT_UNSUPPORTED) == 0 && - (feature_incompat & EXT2_FEATURE_INCOMPAT_UNSUPPORTED) == 0) { - id->type = "ext2"; - goto found; - } - } -- - return -1; - - found: diff --git a/src/patches/udev-141_no_netif_rename.patch b/src/patches/udev-141_no_netif_rename.patch deleted file mode 100644 index fcc5009..0000000 --- a/src/patches/udev-141_no_netif_rename.patch +++ /dev/null @@ -1,50 +0,0 @@ -diff -Naur udev-141.org/udev/udev-event.c udev-141/udev/udev-event.c ---- udev-141.org/udev/udev-event.c 2009-02-24 15:08:35.000000000 +0100 -+++ udev-141/udev/udev-event.c 2012-10-30 12:27:00.262833136 +0100 -@@ -486,45 +486,8 @@ - if (err == 0) - rename_netif_kernel_log(ifr); - else { -- int loop; -- -- /* see if the destination interface name already exists */ -- if (errno != EEXIST) { -- err(event->udev, "error changing netif name %s to %s: %m\n", -- ifr.ifr_name, ifr.ifr_newname); -- goto exit; -- } -- -- /* free our own name, another process may wait for us */ -- util_strlcpy(ifr.ifr_newname, udev_device_get_sysname(dev), IFNAMSIZ); -- util_strlcat(ifr.ifr_newname, "_rename", IFNAMSIZ); -- err = ioctl(sk, SIOCSIFNAME, &ifr); -- if (err != 0) { -- err(event->udev, "error changing netif name %s to %s: %m\n", -+ err(event->udev, "error changing netif name %s to %s: %m\n", - ifr.ifr_name, ifr.ifr_newname); -- goto exit; -- } -- -- /* wait 90 seconds for our target to become available */ -- util_strlcpy(ifr.ifr_name, ifr.ifr_newname, IFNAMSIZ); -- util_strlcpy(ifr.ifr_newname, event->name, IFNAMSIZ); -- loop = 90 * 20; -- while (loop--) { -- err = ioctl(sk, SIOCSIFNAME, &ifr); -- if (err == 0) { -- rename_netif_kernel_log(ifr); -- break; -- } -- -- if (errno != EEXIST) { -- err(event->udev, "error changing net interface name %s to %s: %m\n", -- ifr.ifr_name, ifr.ifr_newname); -- break; -- } -- dbg(event->udev, "wait for netif '%s' to become free, loop=%i\n", -- event->name, (90 * 20) - loop); -- usleep(1000 * 1000 / 20); -- } - } - exit: - close(sk); diff --git a/src/patches/v4l-dvb_bestunar_us638x.patch b/src/patches/v4l-dvb_bestunar_us638x.patch deleted file mode 100644 index e3ac8d2..0000000 --- a/src/patches/v4l-dvb_bestunar_us638x.patch +++ /dev/null @@ -1,2810 +0,0 @@ -diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Kconfig v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Kconfig ---- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Kconfig 2012-08-22 05:45:23.000000000 +0200 -+++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Kconfig 2012-11-24 13:35:19.220030262 +0100 -@@ -200,6 +200,13 @@ - help - A DVB-S/S2 tuner module. Say Y when you want to support this frontend. - -+config DVB_M88DS3103 -+ tristate "Montage DS3103 based" -+ depends on DVB_CORE && I2C -+ default m if DVB_FE_CUSTOMISE -+ help -+ A DVB-S/S2 tuner module. Say Y when you want to support this frontend. -+ - config DVB_SI21XX - tristate "Silicon Labs SI21XX based" - depends on DVB_CORE && I2C -diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.c v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.c ---- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.c 1970-01-01 01:00:00.000000000 +0100 -+++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.c 2012-11-24 13:34:43.713346302 +0100 -@@ -0,0 +1,1710 @@ -+/* -+ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver -+ -+ Copyright (C) 2011 Max nibblenibble.max@gmail.com -+ Copyright (C) 2010 Montage Technology<www.montage-tech.com> -+ Copyright (C) 2009 Konstantin Dimitrov. -+ -+ 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, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include <linux/slab.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/moduleparam.h> -+#include <linux/init.h> -+#include <linux/firmware.h> -+ -+#include "dvb_frontend.h" -+#include "m88ds3103.h" -+#include "m88ds3103_priv.h" -+ -+static int debug; -+module_param(debug, int, 0644); -+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); -+ -+#define dprintk(args...) \ -+ do { \ -+ if (debug) \ -+ printk(KERN_INFO "m88ds3103: " args); \ -+ } while (0) -+ -+/*demod register operations.*/ -+static int m88ds3103_writereg(struct m88ds3103_state *state, int reg, int data) -+{ -+ u8 buf[] = { reg, data }; -+ struct i2c_msg msg = { .addr = state->config->demod_address, -+ .flags = 0, .buf = buf, .len = 2 }; -+ int err; -+ -+ if (debug > 1) -+ printk("m88ds3103: %s: write reg 0x%02x, value 0x%02x\n", -+ __func__, reg, data); -+ -+ err = i2c_transfer(state->i2c, &msg, 1); -+ if (err != 1) { -+ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," -+ " value == 0x%02x)\n", __func__, err, reg, data); -+ return -EREMOTEIO; -+ } -+ return 0; -+} -+ -+static int m88ds3103_readreg(struct m88ds3103_state *state, u8 reg) -+{ -+ int ret; -+ u8 b0[] = { reg }; -+ u8 b1[] = { 0 }; -+ struct i2c_msg msg[] = { -+ { .addr = state->config->demod_address, .flags = 0, -+ .buf = b0, .len = 1 }, -+ { .addr = state->config->demod_address, .flags = I2C_M_RD, -+ .buf = b1, .len = 1 } -+ }; -+ ret = i2c_transfer(state->i2c, msg, 2); -+ -+ if (ret != 2) { -+ printk(KERN_ERR "%s: reg=0x%x (error=%d)\n", -+ __func__, reg, ret); -+ return ret; -+ } -+ -+ if (debug > 1) -+ printk(KERN_INFO "m88ds3103: read reg 0x%02x, value 0x%02x\n", -+ reg, b1[0]); -+ -+ return b1[0]; -+} -+ -+/*tuner register operations.*/ -+static int m88ds3103_tuner_writereg(struct m88ds3103_state *state, int reg, int data) -+{ -+ u8 buf[] = { reg, data }; -+ struct i2c_msg msg = { .addr = 0x60, -+ .flags = 0, .buf = buf, .len = 2 }; -+ int err; -+ -+ m88ds3103_writereg(state, 0x03, 0x11); -+ err = i2c_transfer(state->i2c, &msg, 1); -+ -+ if (err != 1) { -+ printk("%s: writereg error(err == %i, reg == 0x%02x," -+ " value == 0x%02x)\n", __func__, err, reg, data); -+ return -EREMOTEIO; -+ } -+ -+ return 0; -+} -+ -+static int m88ds3103_tuner_readreg(struct m88ds3103_state *state, u8 reg) -+{ -+ int ret; -+ u8 b0[] = { reg }; -+ u8 b1[] = { 0 }; -+ struct i2c_msg msg[] = { -+ { .addr = 0x60, .flags = 0, -+ .buf = b0, .len = 1 }, -+ { .addr = 0x60, .flags = I2C_M_RD, -+ .buf = b1, .len = 1 } -+ }; -+ -+ m88ds3103_writereg(state, 0x03, 0x11); -+ ret = i2c_transfer(state->i2c, msg, 2); -+ -+ if (ret != 2) { -+ printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret); -+ return ret; -+ } -+ -+ return b1[0]; -+} -+ -+/* Bulk demod I2C write, for firmware download. */ -+static int m88ds3103_writeregN(struct m88ds3103_state *state, int reg, -+ const u8 *data, u16 len) -+{ -+ int ret = -EREMOTEIO; -+ struct i2c_msg msg; -+ u8 *buf; -+ -+ buf = kmalloc(len + 1, GFP_KERNEL); -+ if (buf == NULL) { -+ printk("Unable to kmalloc\n"); -+ ret = -ENOMEM; -+ goto error; -+ } -+ -+ *(buf) = reg; -+ memcpy(buf + 1, data, len); -+ -+ msg.addr = state->config->demod_address; -+ msg.flags = 0; -+ msg.buf = buf; -+ msg.len = len + 1; -+ -+ if (debug > 1) -+ printk(KERN_INFO "m88ds3103: %s: write regN 0x%02x, len = %d\n", -+ __func__, reg, len); -+ -+ ret = i2c_transfer(state->i2c, &msg, 1); -+ if (ret != 1) { -+ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n", -+ __func__, ret, reg); -+ ret = -EREMOTEIO; -+ } -+ -+error: -+ kfree(buf); -+ -+ return ret; -+} -+ -+static int m88ds3103_load_firmware(struct dvb_frontend *fe) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ const struct firmware *fw; -+ int i, ret = 0; -+ -+ dprintk("%s()\n", __func__); -+ -+ if (state->skip_fw_load) -+ return 0; -+ /* Load firmware */ -+ /* request the firmware, this will block until someone uploads it */ -+ if(state->demod_id == DS3000_ID){ -+ printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__, -+ DS3000_DEFAULT_FIRMWARE); -+ ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE, -+ state->i2c->dev.parent); -+ }else if(state->demod_id == DS3103_ID){ -+ printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__, -+ DS3103_DEFAULT_FIRMWARE); -+ ret = request_firmware(&fw, DS3103_DEFAULT_FIRMWARE, -+ state->i2c->dev.parent); -+ } -+ -+ printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__); -+ if (ret) { -+ printk(KERN_ERR "%s: No firmware uploaded (timeout or file not " -+ "found?)\n", __func__); -+ return ret; -+ } -+ -+ /* Make sure we don't recurse back through here during loading */ -+ state->skip_fw_load = 1; -+ -+ dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n", -+ fw->size, -+ fw->data[0], -+ fw->data[1], -+ fw->data[fw->size - 2], -+ fw->data[fw->size - 1]); -+ -+ /* stop internal mcu. */ -+ m88ds3103_writereg(state, 0xb2, 0x01); -+ /* split firmware to download.*/ -+ for(i = 0; i < FW_DOWN_LOOP; i++){ -+ ret = m88ds3103_writeregN(state, 0xb0, &(fw->data[FW_DOWN_SIZE*i]), FW_DOWN_SIZE); -+ if(ret != 1) break; -+ } -+ /* start internal mcu. */ -+ if(ret == 1) -+ m88ds3103_writereg(state, 0xb2, 0x00); -+ -+ release_firmware(fw); -+ -+ dprintk("%s: Firmware upload %s\n", __func__, -+ ret == 1 ? "complete" : "failed"); -+ -+ if(ret == 1) ret = 0; -+ -+ /* Ensure firmware is always loaded if required */ -+ state->skip_fw_load = 0; -+ -+ return ret; -+} -+ -+ -+static int m88ds3103_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ u8 data; -+ -+ dprintk("%s(%d)\n", __func__, voltage); -+ -+ dprintk("m88ds3103:pin_ctrl = (%02x)\n", state->config->pin_ctrl); -+ -+ if(state->config->set_voltage) -+ state->config->set_voltage(fe, voltage); -+ -+ data = m88ds3103_readreg(state, 0xa2); -+ -+ if(state->config->pin_ctrl & 0x80){ /*If control pin is assigned.*/ -+ data &= ~0x03; /* bit0 V/H, bit1 off/on */ -+ if(state->config->pin_ctrl & 0x02) -+ data |= 0x02; -+ -+ switch (voltage) { -+ case SEC_VOLTAGE_18: -+ if((state->config->pin_ctrl & 0x01) == 0) -+ data |= 0x01; -+ break; -+ case SEC_VOLTAGE_13: -+ if(state->config->pin_ctrl & 0x01) -+ data |= 0x01; -+ break; -+ case SEC_VOLTAGE_OFF: -+ if(state->config->pin_ctrl & 0x02) -+ data &= ~0x02; -+ else -+ data |= 0x02; -+ break; -+ } -+ } -+ -+ m88ds3103_writereg(state, 0xa2, data); -+ -+ return 0; -+} -+ -+static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t* status) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ int lock = 0; -+ -+ *status = 0; -+ -+ switch (state->delivery_system){ -+ case SYS_DVBS: -+ lock = m88ds3103_readreg(state, 0xd1); -+ dprintk("%s: SYS_DVBS status=%x.\n", __func__, lock); -+ -+ if ((lock & 0x07) == 0x07){ -+ /*if((m88ds3103_readreg(state, 0x0d) & 0x07) == 0x07)*/ -+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER -+ | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; -+ -+ } -+ break; -+ case SYS_DVBS2: -+ lock = m88ds3103_readreg(state, 0x0d); -+ dprintk("%s: SYS_DVBS2 status=%x.\n", __func__, lock); -+ -+ if ((lock & 0x8f) == 0x8f) -+ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER -+ | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; -+ -+ break; -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+static int m88ds3103_read_ber(struct dvb_frontend *fe, u32* ber) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ u8 tmp1, tmp2, tmp3; -+ u32 ldpc_frame_cnt, pre_err_packags, code_rate_fac = 0; -+ -+ dprintk("%s()\n", __func__); -+ -+ switch (state->delivery_system) { -+ case SYS_DVBS: -+ m88ds3103_writereg(state, 0xf9, 0x04); -+ tmp3 = m88ds3103_readreg(state, 0xf8); -+ if ((tmp3&0x10) == 0){ -+ tmp1 = m88ds3103_readreg(state, 0xf7); -+ tmp2 = m88ds3103_readreg(state, 0xf6); -+ tmp3 |= 0x10; -+ m88ds3103_writereg(state, 0xf8, tmp3); -+ state->preBer = (tmp1<<8) | tmp2; -+ } -+ break; -+ case SYS_DVBS2: -+ tmp1 = m88ds3103_readreg(state, 0x7e) & 0x0f; -+ switch(tmp1){ -+ case 0: code_rate_fac = 16008 - 80; break; -+ case 1: code_rate_fac = 21408 - 80; break; -+ case 2: code_rate_fac = 25728 - 80; break; -+ case 3: code_rate_fac = 32208 - 80; break; -+ case 4: code_rate_fac = 38688 - 80; break; -+ case 5: code_rate_fac = 43040 - 80; break; -+ case 6: code_rate_fac = 48408 - 80; break; -+ case 7: code_rate_fac = 51648 - 80; break; -+ case 8: code_rate_fac = 53840 - 80; break; -+ case 9: code_rate_fac = 57472 - 80; break; -+ case 10: code_rate_fac = 58192 - 80; break; -+ } -+ -+ tmp1 = m88ds3103_readreg(state, 0xd7) & 0xff; -+ tmp2 = m88ds3103_readreg(state, 0xd6) & 0xff; -+ tmp3 = m88ds3103_readreg(state, 0xd5) & 0xff; -+ ldpc_frame_cnt = (tmp1 << 16) | (tmp2 << 8) | tmp3; -+ -+ tmp1 = m88ds3103_readreg(state, 0xf8) & 0xff; -+ tmp2 = m88ds3103_readreg(state, 0xf7) & 0xff; -+ pre_err_packags = tmp1<<8 | tmp2; -+ -+ if (ldpc_frame_cnt > 1000){ -+ m88ds3103_writereg(state, 0xd1, 0x01); -+ m88ds3103_writereg(state, 0xf9, 0x01); -+ m88ds3103_writereg(state, 0xf9, 0x00); -+ m88ds3103_writereg(state, 0xd1, 0x00); -+ state->preBer = pre_err_packags; -+ } -+ break; -+ default: -+ break; -+ } -+ *ber = state->preBer; -+ -+ return 0; -+} -+ -+static int m88ds3103_read_signal_strength(struct dvb_frontend *fe, -+ u16 *signal_strength) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ u16 gain; -+ u8 gain1, gain2, gain3 = 0; -+ -+ dprintk("%s()\n", __func__); -+ -+ gain1 = m88ds3103_tuner_readreg(state, 0x3d) & 0x1f; -+ dprintk("%s: gain1 = 0x%02x \n", __func__, gain1); -+ -+ if (gain1 > 15) gain1 = 15; -+ gain2 = m88ds3103_tuner_readreg(state, 0x21) & 0x1f; -+ dprintk("%s: gain2 = 0x%02x \n", __func__, gain2); -+ -+ if(state->tuner_id == TS2022_ID){ -+ gain3 = (m88ds3103_tuner_readreg(state, 0x66)>>3) & 0x07; -+ dprintk("%s: gain3 = 0x%02x \n", __func__, gain3); -+ -+ if (gain2 > 16) gain2 = 16; -+ if (gain2 < 2) gain2 = 2; -+ if (gain3 > 6) gain3 = 6; -+ }else{ -+ if (gain2 > 13) gain2 = 13; -+ gain3 = 0; -+ } -+ -+ gain = gain1*23 + gain2*35 + gain3*29; -+ *signal_strength = 60000 - gain*55; -+ -+ return 0; -+} -+ -+ -+static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *p_snr) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ u8 val, npow1, npow2, spow1, cnt; -+ u16 tmp, snr; -+ u32 npow, spow, snr_total; -+ static const u16 mes_log10[] ={ -+ 0, 3010, 4771, 6021, 6990, 7781, 8451, 9031, 9542, 10000, -+ 10414, 10792, 11139, 11461, 11761, 12041, 12304, 12553, 12788, 13010, -+ 13222, 13424, 13617, 13802, 13979, 14150, 14314, 14472, 14624, 14771, -+ 14914, 15052, 15185, 15315, 15441, 15563, 15682, 15798, 15911, 16021, -+ 16128, 16232, 16335, 16435, 16532, 16628, 16721, 16812, 16902, 16990, -+ 17076, 17160, 17243, 17324, 17404, 17482, 17559, 17634, 17709, 17782, -+ 17853, 17924, 17993, 18062, 18129, 18195, 18261, 18325, 18388, 18451, -+ 18513, 18573, 18633, 18692, 18751, 18808, 18865, 18921, 18976, 19031 -+ }; -+ static const u16 mes_loge[] ={ -+ 0, 6931, 10986, 13863, 16094, 17918, 19459, 20794, 21972, 23026, -+ 23979, 24849, 25649, 26391, 27081, 27726, 28332, 28904, 29444, 29957, -+ 30445, 30910, 31355, 31781, 32189, 32581, 32958, 33322, 33673, 34012, -+ 34340, 34657, -+ }; -+ -+ dprintk("%s()\n", __func__); -+ -+ snr = 0; -+ -+ switch (state->delivery_system){ -+ case SYS_DVBS: -+ cnt = 10; snr_total = 0; -+ while(cnt > 0){ -+ val = m88ds3103_readreg(state, 0xff); -+ snr_total += val; -+ cnt--; -+ } -+ tmp = (u16)(snr_total/80); -+ if(tmp > 0){ -+ if (tmp > 32) tmp = 32; -+ snr = (mes_loge[tmp - 1] * 100) / 45; -+ }else{ -+ snr = 0; -+ } -+ break; -+ case SYS_DVBS2: -+ cnt = 10; npow = 0; spow = 0; -+ while(cnt >0){ -+ npow1 = m88ds3103_readreg(state, 0x8c) & 0xff; -+ npow2 = m88ds3103_readreg(state, 0x8d) & 0xff; -+ npow += (((npow1 & 0x3f) + (u16)(npow2 << 6)) >> 2); -+ -+ spow1 = m88ds3103_readreg(state, 0x8e) & 0xff; -+ spow += ((spow1 * spow1) >> 1); -+ cnt--; -+ } -+ npow /= 10; spow /= 10; -+ if(spow == 0){ -+ snr = 0; -+ }else if(npow == 0){ -+ snr = 19; -+ }else{ -+ if(spow > npow){ -+ tmp = (u16)(spow / npow); -+ if (tmp > 80) tmp = 80; -+ snr = mes_log10[tmp - 1]*3; -+ }else{ -+ tmp = (u16)(npow / spow); -+ if (tmp > 80) tmp = 80; -+ snr = -(mes_log10[tmp - 1] / 1000); -+ } -+ } -+ break; -+ default: -+ break; -+ } -+ *p_snr = snr; -+ -+ return 0; -+} -+ -+ -+static int m88ds3103_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ u8 tmp1, tmp2, tmp3, data; -+ -+ dprintk("%s()\n", __func__); -+ -+ switch (state->delivery_system) { -+ case SYS_DVBS: -+ data = m88ds3103_readreg(state, 0xf8); -+ data |= 0x40; -+ m88ds3103_writereg(state, 0xf8, data); -+ tmp1 = m88ds3103_readreg(state, 0xf5); -+ tmp2 = m88ds3103_readreg(state, 0xf4); -+ *ucblocks = (tmp1 <<8) | tmp2; -+ data &= ~0x20; -+ m88ds3103_writereg(state, 0xf8, data); -+ data |= 0x20; -+ m88ds3103_writereg(state, 0xf8, data); -+ data &= ~0x40; -+ m88ds3103_writereg(state, 0xf8, data); -+ break; -+ case SYS_DVBS2: -+ tmp1 = m88ds3103_readreg(state, 0xda); -+ tmp2 = m88ds3103_readreg(state, 0xd9); -+ tmp3 = m88ds3103_readreg(state, 0xd8); -+ *ucblocks = (tmp1 <<16)|(tmp2 <<8)|tmp3; -+ data = m88ds3103_readreg(state, 0xd1); -+ data |= 0x01; -+ m88ds3103_writereg(state, 0xd1, data); -+ data &= ~0x01; -+ m88ds3103_writereg(state, 0xd1, data); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+static int m88ds3103_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ u8 data_a1, data_a2; -+ -+ dprintk("%s(%d)\n", __func__, tone); -+ if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { -+ printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone); -+ return -EINVAL; -+ } -+ -+ data_a1 = m88ds3103_readreg(state, 0xa1); -+ data_a2 = m88ds3103_readreg(state, 0xa2); -+ if(state->demod_id == DS3103_ID) -+ data_a2 &= 0xdf; /* Normal mode */ -+ switch (tone) { -+ case SEC_TONE_ON: -+ dprintk("%s: SEC_TONE_ON\n", __func__); -+ data_a1 |= 0x04; -+ data_a1 &= ~0x03; -+ data_a1 &= ~0x40; -+ data_a2 &= ~0xc0; -+ break; -+ case SEC_TONE_OFF: -+ dprintk("%s: SEC_TONE_OFF\n", __func__); -+ data_a2 &= ~0xc0; -+ data_a2 |= 0x80; -+ break; -+ } -+ m88ds3103_writereg(state, 0xa2, data_a2); -+ m88ds3103_writereg(state, 0xa1, data_a1); -+ return 0; -+} -+ -+static int m88ds3103_send_diseqc_msg(struct dvb_frontend *fe, -+ struct dvb_diseqc_master_cmd *d) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ int i, ret = 0; -+ u8 tmp, time_out; -+ -+ /* Dump DiSEqC message */ -+ if (debug) { -+ printk(KERN_INFO "m88ds3103: %s(", __func__); -+ for (i = 0 ; i < d->msg_len ;) { -+ printk(KERN_INFO "0x%02x", d->msg[i]); -+ if (++i < d->msg_len) -+ printk(KERN_INFO ", "); -+ } -+ } -+ -+ tmp = m88ds3103_readreg(state, 0xa2); -+ tmp &= ~0xc0; -+ if(state->demod_id == DS3103_ID) -+ tmp &= ~0x20; -+ m88ds3103_writereg(state, 0xa2, tmp); -+ -+ for (i = 0; i < d->msg_len; i ++) -+ m88ds3103_writereg(state, (0xa3+i), d->msg[i]); -+ -+ tmp = m88ds3103_readreg(state, 0xa1); -+ tmp &= ~0x38; -+ tmp &= ~0x40; -+ tmp |= ((d->msg_len-1) << 3) | 0x07; -+ tmp &= ~0x80; -+ m88ds3103_writereg(state, 0xa1, tmp); -+ /* 1.5 * 9 * 8 = 108ms */ -+ time_out = 150; -+ while (time_out > 0){ -+ msleep(10); -+ time_out -= 10; -+ tmp = m88ds3103_readreg(state, 0xa1); -+ if ((tmp & 0x40) == 0) -+ break; -+ } -+ if (time_out == 0){ -+ tmp = m88ds3103_readreg(state, 0xa1); -+ tmp &= ~0x80; -+ tmp |= 0x40; -+ m88ds3103_writereg(state, 0xa1, tmp); -+ ret = 1; -+ } -+ tmp = m88ds3103_readreg(state, 0xa2); -+ tmp &= ~0xc0; -+ tmp |= 0x80; -+ m88ds3103_writereg(state, 0xa2, tmp); -+ return ret; -+} -+ -+ -+static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe, -+ fe_sec_mini_cmd_t burst) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ u8 val, time_out; -+ -+ dprintk("%s()\n", __func__); -+ -+ val = m88ds3103_readreg(state, 0xa2); -+ val &= ~0xc0; -+ if(state->demod_id == DS3103_ID) -+ val &= 0xdf; /* Normal mode */ -+ m88ds3103_writereg(state, 0xa2, val); -+ /* DiSEqC burst */ -+ if (burst == SEC_MINI_B) -+ m88ds3103_writereg(state, 0xa1, 0x01); -+ else -+ m88ds3103_writereg(state, 0xa1, 0x02); -+ -+ msleep(13); -+ -+ time_out = 5; -+ do{ -+ val = m88ds3103_readreg(state, 0xa1); -+ if ((val & 0x40) == 0) -+ break; -+ msleep(1); -+ time_out --; -+ } while (time_out > 0); -+ -+ val = m88ds3103_readreg(state, 0xa2); -+ val &= ~0xc0; -+ val |= 0x80; -+ m88ds3103_writereg(state, 0xa2, val); -+ -+ return 0; -+} -+ -+static void m88ds3103_release(struct dvb_frontend *fe) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ -+ dprintk("%s\n", __func__); -+ kfree(state); -+} -+ -+static int m88ds3103_check_id(struct m88ds3103_state *state) -+{ -+ int val_00, val_01; -+ -+ /*check demod id*/ -+ val_01 = m88ds3103_readreg(state, 0x01); -+ printk(KERN_INFO "DS3000 chip version: %x attached.\n", val_01); -+ -+ if(val_01 == 0xD0) -+ state->demod_id = DS3103_ID; -+ else if(val_01 == 0xC0) -+ state->demod_id = DS3000_ID; -+ else -+ state->demod_id = UNKNOW_ID; -+ -+ /*check tuner id*/ -+ val_00 = m88ds3103_tuner_readreg(state, 0x00); -+ printk(KERN_INFO "TS202x chip version[1]: %x attached.\n", val_00); -+ val_00 &= 0x03; -+ if(val_00 == 0) -+ { -+ m88ds3103_tuner_writereg(state, 0x00, 0x01); -+ msleep(3); -+ } -+ m88ds3103_tuner_writereg(state, 0x00, 0x03); -+ msleep(5); -+ -+ val_00 = m88ds3103_tuner_readreg(state, 0x00); -+ printk(KERN_INFO "TS202x chip version[2]: %x attached.\n", val_00); -+ val_00 &= 0xff; -+ if((val_00 == 0x01) || (val_00 == 0x41) || (val_00 == 0x81)) -+ state->tuner_id = TS2020_ID; -+ else if(((val_00 & 0xc0)== 0xc0) || (val_00 == 0x83)) -+ state->tuner_id = TS2022_ID; -+ else -+ state->tuner_id = UNKNOW_ID; -+ -+ return state->demod_id; -+} -+ -+static struct dvb_frontend_ops m88ds3103_ops; -+static int m88ds3103_initilaze(struct dvb_frontend *fe); -+ -+struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *config, -+ struct i2c_adapter *i2c) -+{ -+ struct m88ds3103_state *state = NULL; -+ -+ dprintk("%s\n", __func__); -+ -+ /* allocate memory for the internal state */ -+ state = kzalloc(sizeof(struct m88ds3103_state), GFP_KERNEL); -+ if (state == NULL) { -+ printk(KERN_ERR "Unable to kmalloc\n"); -+ goto error2; -+ } -+ -+ state->config = config; -+ state->i2c = i2c; -+ state->preBer = 0xffff; -+ state->delivery_system = SYS_DVBS; /*Default to DVB-S.*/ -+ -+ /* check demod id */ -+ if(m88ds3103_check_id(state) == UNKNOW_ID){ -+ printk(KERN_ERR "Unable to find Montage chip\n"); -+ goto error3; -+ } -+ -+ memcpy(&state->frontend.ops, &m88ds3103_ops, -+ sizeof(struct dvb_frontend_ops)); -+ state->frontend.demodulator_priv = state; -+ -+ m88ds3103_initilaze(&state->frontend); -+ -+ return &state->frontend; -+ -+error3: -+ kfree(state); -+error2: -+ return NULL; -+} -+EXPORT_SYMBOL(m88ds3103_attach); -+ -+static int m88ds3103_set_carrier_offset(struct dvb_frontend *fe, -+ s32 carrier_offset_khz) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ s32 tmp; -+ -+ tmp = carrier_offset_khz; -+ tmp *= 65536; -+ -+ tmp = (2*tmp + MT_FE_MCLK_KHZ) / (2*MT_FE_MCLK_KHZ); -+ -+ if (tmp < 0) -+ tmp += 65536; -+ -+ m88ds3103_writereg(state, 0x5f, tmp >> 8); -+ m88ds3103_writereg(state, 0x5e, tmp & 0xff); -+ -+ return 0; -+} -+ -+static int m88ds3103_set_symrate(struct dvb_frontend *fe) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ u16 value; -+ -+ value = (((c->symbol_rate / 1000) << 15) + (MT_FE_MCLK_KHZ / 4)) / (MT_FE_MCLK_KHZ / 2); -+ m88ds3103_writereg(state, 0x61, value & 0x00ff); -+ m88ds3103_writereg(state, 0x62, (value & 0xff00) >> 8); -+ -+ return 0; -+} -+ -+static int m88ds3103_set_CCI(struct dvb_frontend *fe) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ u8 tmp; -+ -+ tmp = m88ds3103_readreg(state, 0x56); -+ tmp &= ~0x01; -+ m88ds3103_writereg(state, 0x56, tmp); -+ -+ tmp = m88ds3103_readreg(state, 0x76); -+ tmp &= ~0x80; -+ m88ds3103_writereg(state, 0x76, tmp); -+ -+ return 0; -+} -+ -+static int m88ds3103_init_reg(struct m88ds3103_state *state, const u8 *p_reg_tab, u32 size) -+{ -+ u32 i; -+ -+ for(i = 0; i < size; i+=2) -+ m88ds3103_writereg(state, p_reg_tab[i], p_reg_tab[i+1]); -+ -+ return 0; -+} -+ -+static int m88ds3103_get_locked_sym_rate(struct m88ds3103_state *state, u32 *sym_rate_KSs) -+{ -+ u16 tmp; -+ u32 sym_rate_tmp; -+ u8 val_0x6d, val_0x6e; -+ -+ val_0x6d = m88ds3103_readreg(state, 0x6d); -+ val_0x6e = m88ds3103_readreg(state, 0x6e); -+ -+ tmp = (u16)((val_0x6e<<8) | val_0x6d); -+ -+ sym_rate_tmp = (u32)(tmp * MT_FE_MCLK_KHZ); -+ sym_rate_tmp = (u32)(sym_rate_tmp / (1<<16)); -+ *sym_rate_KSs = sym_rate_tmp; -+ -+ return 0; -+} -+ -+static int m88ds3103_get_channel_info(struct m88ds3103_state *state, u8 *p_mode, u8 *p_coderate) -+{ -+ u8 tmp, val_0x7E; -+ -+ if(state->delivery_system == SYS_DVBS2){ -+ val_0x7E = m88ds3103_readreg(state, 0x7e); -+ tmp = (u8)((val_0x7E&0xC0) >> 6); -+ *p_mode = tmp; -+ tmp = (u8)(val_0x7E & 0x0f); -+ *p_coderate = tmp; -+ } else { -+ *p_mode = 0; -+ tmp = m88ds3103_readreg(state, 0xe6); -+ tmp = (u8)(tmp >> 5); -+ *p_coderate = tmp; -+ } -+ -+ return 0; -+} -+ -+static int m88ds3103_set_clock_ratio(struct m88ds3103_state *state) -+{ -+ u8 val, mod_fac, tmp1, tmp2; -+ u32 input_datarate, locked_sym_rate_KSs; -+ u32 MClk_KHz = 96000; -+ u8 mod_mode, code_rate, divid_ratio = 0; -+ -+ locked_sym_rate_KSs = 0; -+ m88ds3103_get_locked_sym_rate(state, &locked_sym_rate_KSs); -+ if(locked_sym_rate_KSs == 0) -+ return 0; -+ -+ m88ds3103_get_channel_info(state, &mod_mode, &code_rate); -+ -+ if (state->delivery_system == SYS_DVBS2) -+ { -+ switch(mod_mode) { -+ case 1: mod_fac = 3; break; -+ case 2: mod_fac = 4; break; -+ case 3: mod_fac = 5; break; -+ default: mod_fac = 2; break; -+ } -+ -+ switch(code_rate) { -+ case 0: input_datarate = locked_sym_rate_KSs*mod_fac/8/4; break; -+ case 1: input_datarate = locked_sym_rate_KSs*mod_fac/8/3; break; -+ case 2: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/5; break; -+ case 3: input_datarate = locked_sym_rate_KSs*mod_fac/8/2; break; -+ case 4: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/5; break; -+ case 5: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3; break; -+ case 6: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/4; break; -+ case 7: input_datarate = locked_sym_rate_KSs*mod_fac*4/8/5; break; -+ case 8: input_datarate = locked_sym_rate_KSs*mod_fac*5/8/6; break; -+ case 9: input_datarate = locked_sym_rate_KSs*mod_fac*8/8/9; break; -+ case 10: input_datarate = locked_sym_rate_KSs*mod_fac*9/8/10; break; -+ default: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3; break; -+ } -+ -+ if(state->demod_id == DS3000_ID) -+ input_datarate = input_datarate * 115 / 100; -+ -+ if(input_datarate < 4800) {tmp1 = 15;tmp2 = 15;} //4.8MHz TS clock -+ else if(input_datarate < 4966) {tmp1 = 14;tmp2 = 15;} //4.966MHz TS clock -+ else if(input_datarate < 5143) {tmp1 = 14;tmp2 = 14;} //5.143MHz TS clock -+ else if(input_datarate < 5333) {tmp1 = 13;tmp2 = 14;} //5.333MHz TS clock -+ else if(input_datarate < 5538) {tmp1 = 13;tmp2 = 13;} //5.538MHz TS clock -+ else if(input_datarate < 5760) {tmp1 = 12;tmp2 = 13;} //5.76MHz TS clock allan 0809 -+ else if(input_datarate < 6000) {tmp1 = 12;tmp2 = 12;} //6MHz TS clock -+ else if(input_datarate < 6260) {tmp1 = 11;tmp2 = 12;} //6.26MHz TS clock -+ else if(input_datarate < 6545) {tmp1 = 11;tmp2 = 11;} //6.545MHz TS clock -+ else if(input_datarate < 6857) {tmp1 = 10;tmp2 = 11;} //6.857MHz TS clock -+ else if(input_datarate < 7200) {tmp1 = 10;tmp2 = 10;} //7.2MHz TS clock -+ else if(input_datarate < 7578) {tmp1 = 9;tmp2 = 10;} //7.578MHz TS clock -+ else if(input_datarate < 8000) {tmp1 = 9;tmp2 = 9;} //8MHz TS clock -+ else if(input_datarate < 8470) {tmp1 = 8;tmp2 = 9;} //8.47MHz TS clock -+ else if(input_datarate < 9000) {tmp1 = 8;tmp2 = 8;} //9MHz TS clock -+ else if(input_datarate < 9600) {tmp1 = 7;tmp2 = 8;} //9.6MHz TS clock -+ else if(input_datarate < 10285) {tmp1 = 7;tmp2 = 7;} //10.285MHz TS clock -+ else if(input_datarate < 12000) {tmp1 = 6;tmp2 = 6;} //12MHz TS clock -+ else if(input_datarate < 14400) {tmp1 = 5;tmp2 = 5;} //14.4MHz TS clock -+ else if(input_datarate < 18000) {tmp1 = 4;tmp2 = 4;} //18MHz TS clock -+ else {tmp1 = 3;tmp2 = 3;} //24MHz TS clock -+ -+ if(state->demod_id == DS3000_ID) { -+ val = (u8)((tmp1<<4) + tmp2); -+ m88ds3103_writereg(state, 0xfe, val); -+ } else { -+ tmp1 = m88ds3103_readreg(state, 0x22); -+ tmp2 = m88ds3103_readreg(state, 0x24); -+ -+ tmp1 >>= 6; -+ tmp1 &= 0x03; -+ tmp2 >>= 6; -+ tmp2 &= 0x03; -+ -+ if((tmp1 == 0x00) && (tmp2 == 0x01)) -+ MClk_KHz = 144000; -+ else if((tmp1 == 0x00) && (tmp2 == 0x03)) -+ MClk_KHz = 72000; -+ else if((tmp1 == 0x01) && (tmp2 == 0x01)) -+ MClk_KHz = 115200; -+ else if((tmp1 == 0x02) && (tmp2 == 0x01)) -+ MClk_KHz = 96000; -+ else if((tmp1 == 0x03) && (tmp2 == 0x00)) -+ MClk_KHz = 192000; -+ else -+ return 0; -+ -+ if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/ -+ input_datarate = 5200; -+ -+ if(input_datarate != 0) -+ divid_ratio = (u8)(MClk_KHz / input_datarate); -+ else -+ divid_ratio = 0xFF; -+ -+ if(divid_ratio > 128) -+ divid_ratio = 128; -+ -+ if(divid_ratio < 2) -+ divid_ratio = 2; -+ -+ tmp1 = (u8)(divid_ratio / 2); -+ tmp2 = (u8)(divid_ratio / 2); -+ -+ if((divid_ratio % 2) != 0) -+ tmp2 += 1; -+ -+ tmp1 -= 1; -+ tmp2 -= 1; -+ -+ tmp1 &= 0x3f; -+ tmp2 &= 0x3f; -+ -+ val = m88ds3103_readreg(state, 0xfe); -+ val &= 0xF0; -+ val |= (tmp2 >> 2) & 0x0f; -+ m88ds3103_writereg(state, 0xfe, val); -+ -+ val = (u8)((tmp2 & 0x03) << 6); -+ val |= tmp1; -+ m88ds3103_writereg(state, 0xea, val); -+ } -+ } else { -+ mod_fac = 2; -+ -+ switch(code_rate) { -+ case 4: input_datarate = locked_sym_rate_KSs*mod_fac/2/8; break; -+ case 3: input_datarate = locked_sym_rate_KSs*mod_fac*2/3/8; break; -+ case 2: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8; break; -+ case 1: input_datarate = locked_sym_rate_KSs*mod_fac*5/6/8; break; -+ case 0: input_datarate = locked_sym_rate_KSs*mod_fac*7/8/8; break; -+ default: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8; break; -+ } -+ -+ if(state->demod_id == DS3000_ID) -+ input_datarate = input_datarate * 115 / 100; -+ -+ if(input_datarate < 6857) {tmp1 = 7;tmp2 = 7;} //6.857MHz TS clock -+ else if(input_datarate < 7384) {tmp1 = 6;tmp2 = 7;} //7.384MHz TS clock -+ else if(input_datarate < 8000) {tmp1 = 6;tmp2 = 6;} //8MHz TS clock -+ else if(input_datarate < 8727) {tmp1 = 5;tmp2 = 6;} //8.727MHz TS clock -+ else if(input_datarate < 9600) {tmp1 = 5;tmp2 = 5;} //9.6MHz TS clock -+ else if(input_datarate < 10666) {tmp1 = 4;tmp2 = 5;} //10.666MHz TS clock -+ else if(input_datarate < 12000) {tmp1 = 4;tmp2 = 4;} //12MHz TS clock -+ else if(input_datarate < 13714) {tmp1 = 3;tmp2 = 4;} //13.714MHz TS clock -+ else if(input_datarate < 16000) {tmp1 = 3;tmp2 = 3;} //16MHz TS clock -+ else if(input_datarate < 19200) {tmp1 = 2;tmp2 = 3;} //19.2MHz TS clock -+ else {tmp1 = 2;tmp2 = 2;} //24MHz TS clock -+ -+ if(state->demod_id == DS3000_ID) { -+ val = m88ds3103_readreg(state, 0xfe); -+ val &= 0xc0; -+ val |= ((u8)((tmp1<<3) + tmp2)); -+ m88ds3103_writereg(state, 0xfe, val); -+ } else { -+ if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/ -+ input_datarate = 5200; -+ -+ if(input_datarate != 0) -+ divid_ratio = (u8)(MClk_KHz / input_datarate); -+ else -+ divid_ratio = 0xFF; -+ -+ if(divid_ratio > 128) -+ divid_ratio = 128; -+ -+ if(divid_ratio < 2) -+ divid_ratio = 2; -+ -+ tmp1 = (u8)(divid_ratio / 2); -+ tmp2 = (u8)(divid_ratio / 2); -+ -+ if((divid_ratio % 2) != 0) -+ tmp2 += 1; -+ -+ tmp1 -= 1; -+ tmp2 -= 1; -+ -+ tmp1 &= 0x3f; -+ tmp2 &= 0x3f; -+ -+ val = m88ds3103_readreg(state, 0xfe); -+ val &= 0xF0; -+ val |= (tmp2 >> 2) & 0x0f; -+ m88ds3103_writereg(state, 0xfe, val); -+ -+ val = (u8)((tmp2 & 0x03) << 6); -+ val |= tmp1; -+ m88ds3103_writereg(state, 0xea, val); -+ } -+ } -+ return 0; -+} -+ -+static int m88ds3103_demod_connect(struct dvb_frontend *fe, s32 carrier_offset_khz) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ u16 value; -+ u8 val1,val2,data; -+ -+ dprintk("connect delivery system = %d\n", state->delivery_system); -+ -+ /* ds3000 global reset */ -+ m88ds3103_writereg(state, 0x07, 0x80); -+ m88ds3103_writereg(state, 0x07, 0x00); -+ /* ds3000 build-in uC reset */ -+ m88ds3103_writereg(state, 0xb2, 0x01); -+ /* ds3000 software reset */ -+ m88ds3103_writereg(state, 0x00, 0x01); -+ -+ switch (state->delivery_system) { -+ case SYS_DVBS: -+ /* initialise the demod in DVB-S mode */ -+ if(state->demod_id == DS3000_ID){ -+ m88ds3103_init_reg(state, ds3000_dvbs_init_tab, sizeof(ds3000_dvbs_init_tab)); -+ -+ value = m88ds3103_readreg(state, 0xfe); -+ value &= 0xc0; -+ value |= 0x1b; -+ m88ds3103_writereg(state, 0xfe, value); -+ -+ if(state->config->ci_mode) -+ val1 = 0x80; -+ else if(state->config->ts_mode) -+ val1 = 0x60; -+ else -+ val1 = 0x20; -+ m88ds3103_writereg(state, 0xfd, val1); -+ -+ }else if(state->demod_id == DS3103_ID){ -+ m88ds3103_init_reg(state, ds3103_dvbs_init_tab, sizeof(ds3103_dvbs_init_tab)); -+ -+ /* set ts clock */ -+ if(state->config->ci_mode == 2){ -+ val1 = 6; val2 = 6; -+ }else if(state->config->ts_mode == 0) { -+ val1 = 3; val2 = 3; -+ }else{ -+ val1 = 0; val2 = 0; -+ } -+ val1 -= 1; val2 -= 1; -+ val1 &= 0x3f; val2 &= 0x3f; -+ data = m88ds3103_readreg(state, 0xfe); -+ data &= 0xf0; -+ data |= (val2 >> 2) & 0x0f; -+ m88ds3103_writereg(state, 0xfe, data); -+ data = (val2 & 0x03) << 6; -+ data |= val1; -+ m88ds3103_writereg(state, 0xea, data); -+ -+ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d)); -+ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30)); -+ -+ /* set master clock */ -+ val1 = m88ds3103_readreg(state, 0x22); -+ val2 = m88ds3103_readreg(state, 0x24); -+ -+ val1 &= 0x3f; -+ val2 &= 0x3f; -+ val1 |= 0x80; -+ val2 |= 0x40; -+ -+ m88ds3103_writereg(state, 0x22, val1); -+ m88ds3103_writereg(state, 0x24, val2); -+ -+ if(state->config->ci_mode) -+ val1 = 0x03; -+ else if(state->config->ts_mode) -+ val1 = 0x06; -+ else -+ val1 = 0x42; -+ m88ds3103_writereg(state, 0xfd, val1); -+ } -+ break; -+ case SYS_DVBS2: -+ /* initialise the demod in DVB-S2 mode */ -+ if(state->demod_id == DS3000_ID){ -+ m88ds3103_init_reg(state, ds3000_dvbs2_init_tab, sizeof(ds3000_dvbs2_init_tab)); -+ -+ if (c->symbol_rate >= 30000000) -+ m88ds3103_writereg(state, 0xfe, 0x54); -+ else -+ m88ds3103_writereg(state, 0xfe, 0x98); -+ -+ }else if(state->demod_id == DS3103_ID){ -+ m88ds3103_init_reg(state, ds3103_dvbs2_init_tab, sizeof(ds3103_dvbs2_init_tab)); -+ -+ /* set ts clock */ -+ if(state->config->ci_mode == 2){ -+ val1 = 6; val2 = 6; -+ }else if(state->config->ts_mode == 0){ -+ val1 = 5; val2 = 4; -+ }else{ -+ val1 = 0; val2 = 0; -+ } -+ val1 -= 1; val2 -= 1; -+ val1 &= 0x3f; val2 &= 0x3f; -+ data = m88ds3103_readreg(state, 0xfe); -+ data &= 0xf0; -+ data |= (val2 >> 2) & 0x0f; -+ m88ds3103_writereg(state, 0xfe, data); -+ data = (val2 & 0x03) << 6; -+ data |= val1; -+ m88ds3103_writereg(state, 0xea, data); -+ -+ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d)); -+ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30)); -+ -+ /* set master clock */ -+ val1 = m88ds3103_readreg(state, 0x22); -+ val2 = m88ds3103_readreg(state, 0x24); -+ -+ val1 &= 0x3f; -+ val2 &= 0x3f; -+ if((state->config->ci_mode == 2) || (state->config->ts_mode == 1)){ -+ val1 |= 0x80; -+ val2 |= 0x40; -+ }else{ -+ if (c->symbol_rate >= 28000000){ -+ val1 |= 0xc0; -+ }else if (c->symbol_rate >= 18000000){ -+ val2 |= 0x40; -+ }else{ -+ val1 |= 0x80; -+ val2 |= 0x40; -+ } -+ } -+ m88ds3103_writereg(state, 0x22, val1); -+ m88ds3103_writereg(state, 0x24, val2); -+ } -+ -+ if(state->config->ci_mode) -+ val1 = 0x03; -+ else if(state->config->ts_mode) -+ val1 = 0x06; -+ else -+ val1 = 0x42; -+ m88ds3103_writereg(state, 0xfd, val1); -+ -+ break; -+ default: -+ return 1; -+ } -+ /* disable 27MHz clock output */ -+ m88ds3103_writereg(state, 0x29, 0x80); -+ /* enable ac coupling */ -+ m88ds3103_writereg(state, 0x25, 0x8a); -+ -+ if ((c->symbol_rate / 1000) <= 3000){ -+ m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 32 * 100 / 64 = 400*/ -+ m88ds3103_writereg(state, 0xc8, 0x20); -+ m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/ -+ m88ds3103_writereg(state, 0xc7, 0x00); -+ }else if((c->symbol_rate / 1000) <= 10000){ -+ m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 16 * 100 / 64 = 200*/ -+ m88ds3103_writereg(state, 0xc8, 0x10); -+ m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/ -+ m88ds3103_writereg(state, 0xc7, 0x00); -+ }else{ -+ m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 6 * 100 / 64 = 75*/ -+ m88ds3103_writereg(state, 0xc8, 0x06); -+ m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/ -+ m88ds3103_writereg(state, 0xc7, 0x00); -+ } -+ -+ m88ds3103_set_symrate(fe); -+ -+ m88ds3103_set_CCI(fe); -+ -+ m88ds3103_set_carrier_offset(fe, carrier_offset_khz); -+ -+ /* ds3000 out of software reset */ -+ m88ds3103_writereg(state, 0x00, 0x00); -+ /* start ds3000 build-in uC */ -+ m88ds3103_writereg(state, 0xb2, 0x00); -+ -+ return 0; -+} -+ -+static int m88ds3103_set_frontend(struct dvb_frontend *fe) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ struct dtv_frontend_properties *c = &fe->dtv_property_cache; -+ -+ int i; -+ fe_status_t status; -+ u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf, div4, capCode, changePLL; -+ s32 offset_khz, lpf_offset_KHz; -+ u16 value, ndiv, lpf_coeff; -+ u32 f3db, gdiv28, realFreq; -+ u8 RFgain; -+ -+ dprintk("%s() ", __func__); -+ dprintk("c frequency = %d\n", c->frequency); -+ dprintk("symbol rate = %d\n", c->symbol_rate); -+ dprintk("delivery system = %d\n", c->delivery_system); -+ -+ realFreq = c->frequency; -+ lpf_offset_KHz = 0; -+ if(c->symbol_rate < 5000000){ -+ lpf_offset_KHz = FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz; -+ realFreq += FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz; -+ } -+ -+ if (state->config->set_ts_params) -+ state->config->set_ts_params(fe, 0); -+ -+ div4 = 0; -+ RFgain = 0; -+ if(state->tuner_id == TS2022_ID){ -+ m88ds3103_tuner_writereg(state, 0x10, 0x0a); -+ m88ds3103_tuner_writereg(state, 0x11, 0x40); -+ if (realFreq < 1103000) { -+ m88ds3103_tuner_writereg(state, 0x10, 0x1b); -+ div4 = 1; -+ ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ; -+ }else { -+ ndiv = (realFreq * (6 + 8) * 2)/MT_FE_CRYSTAL_KHZ; -+ } -+ ndiv = ndiv + ndiv%2; -+ if(ndiv < 4095) -+ ndiv = ndiv - 1024; -+ else if (ndiv < 6143) -+ ndiv = ndiv + 1024; -+ else -+ ndiv = ndiv + 3072; -+ -+ m88ds3103_tuner_writereg(state, 0x01, (ndiv & 0x3f00) >> 8); -+ }else{ -+ m88ds3103_tuner_writereg(state, 0x10, 0x00); -+ if (realFreq < 1146000){ -+ m88ds3103_tuner_writereg(state, 0x10, 0x11); -+ div4 = 1; -+ ndiv = (realFreq * (6 + 8) * 4) / MT_FE_CRYSTAL_KHZ; -+ }else{ -+ m88ds3103_tuner_writereg(state, 0x10, 0x01); -+ ndiv = (realFreq * (6 + 8) * 2) / MT_FE_CRYSTAL_KHZ; -+ } -+ ndiv = ndiv + ndiv%2; -+ ndiv = ndiv - 1024; -+ m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8)&0x0f); -+ } -+ /* set pll */ -+ m88ds3103_tuner_writereg(state, 0x02, ndiv & 0x00ff); -+ m88ds3103_tuner_writereg(state, 0x03, 0x06); -+ m88ds3103_tuner_writereg(state, 0x51, 0x0f); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x10); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ -+ if(state->tuner_id == TS2022_ID){ -+ if(( realFreq >= 1650000 ) && (realFreq <= 1850000)){ -+ msleep(5); -+ value = m88ds3103_tuner_readreg(state, 0x14); -+ value &= 0x7f; -+ if(value < 64){ -+ m88ds3103_tuner_writereg(state, 0x10, 0x82); -+ m88ds3103_tuner_writereg(state, 0x11, 0x6f); -+ -+ m88ds3103_tuner_writereg(state, 0x51, 0x0f); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x10); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ } -+ } -+ msleep(5); -+ value = m88ds3103_tuner_readreg(state, 0x14); -+ value &= 0x1f; -+ -+ if(value > 19){ -+ value = m88ds3103_tuner_readreg(state, 0x10); -+ value &= 0x1d; -+ m88ds3103_tuner_writereg(state, 0x10, value); -+ } -+ }else{ -+ msleep(5); -+ value = m88ds3103_tuner_readreg(state, 0x66); -+ changePLL = (((value & 0x80) >> 7) != div4); -+ -+ if(changePLL){ -+ m88ds3103_tuner_writereg(state, 0x10, 0x11); -+ div4 = 1; -+ ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ; -+ ndiv = ndiv + ndiv%2; -+ ndiv = ndiv - 1024; -+ -+ m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8) & 0x0f); -+ m88ds3103_tuner_writereg(state, 0x02, ndiv & 0xff); -+ -+ m88ds3103_tuner_writereg(state, 0x51, 0x0f); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x10); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ } -+ } -+ /*set the RF gain*/ -+ if(state->tuner_id == TS2020_ID) -+ m88ds3103_tuner_writereg(state, 0x60, 0x79); -+ -+ m88ds3103_tuner_writereg(state, 0x51, 0x17); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x08); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ msleep(5); -+ -+ if(state->tuner_id == TS2020_ID){ -+ RFgain = m88ds3103_tuner_readreg(state, 0x3d); -+ RFgain &= 0x0f; -+ if(RFgain < 15){ -+ if(RFgain < 4) -+ RFgain = 0; -+ else -+ RFgain = RFgain -3; -+ value = ((RFgain << 3) | 0x01) & 0x79; -+ m88ds3103_tuner_writereg(state, 0x60, value); -+ m88ds3103_tuner_writereg(state, 0x51, 0x17); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x08); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ } -+ } -+ -+ /* set the LPF */ -+ if(state->tuner_id == TS2022_ID){ -+ m88ds3103_tuner_writereg(state, 0x25, 0x00); -+ m88ds3103_tuner_writereg(state, 0x27, 0x70); -+ m88ds3103_tuner_writereg(state, 0x41, 0x09); -+ m88ds3103_tuner_writereg(state, 0x08, 0x0b); -+ } -+ -+ f3db = ((c->symbol_rate / 1000) *135) / 200 + 2000; -+ f3db += lpf_offset_KHz; -+ if (f3db < 7000) -+ f3db = 7000; -+ if (f3db > 40000) -+ f3db = 40000; -+ -+ gdiv28 = (MT_FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000; -+ m88ds3103_tuner_writereg(state, 0x04, gdiv28 & 0xff); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1b); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x04); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ msleep(5); -+ -+ value = m88ds3103_tuner_readreg(state, 0x26); -+ capCode = value & 0x3f; -+ if(state->tuner_id == TS2022_ID){ -+ m88ds3103_tuner_writereg(state, 0x41, 0x0d); -+ -+ m88ds3103_tuner_writereg(state, 0x51, 0x1b); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x04); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ -+ msleep(2); -+ -+ value = m88ds3103_tuner_readreg(state, 0x26); -+ value &= 0x3f; -+ value = (capCode + value) / 2; -+ } -+ else -+ value = capCode; -+ -+ gdiv28 = gdiv28 * 207 / (value * 2 + 151); -+ mlpf_max = gdiv28 * 135 / 100; -+ mlpf_min = gdiv28 * 78 / 100; -+ if (mlpf_max > 63) -+ mlpf_max = 63; -+ -+ if(state->tuner_id == TS2022_ID) -+ lpf_coeff = 3200; -+ else -+ lpf_coeff = 2766; -+ -+ nlpf = (f3db * gdiv28 * 2 / lpf_coeff / (MT_FE_CRYSTAL_KHZ / 1000) + 1) / 2 ; -+ if (nlpf > 23) nlpf = 23; -+ if (nlpf < 1) nlpf = 1; -+ -+ lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2; -+ -+ if (lpf_mxdiv < mlpf_min){ -+ nlpf++; -+ lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2; -+ } -+ -+ if (lpf_mxdiv > mlpf_max) -+ lpf_mxdiv = mlpf_max; -+ -+ m88ds3103_tuner_writereg(state, 0x04, lpf_mxdiv); -+ m88ds3103_tuner_writereg(state, 0x06, nlpf); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1b); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x04); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ msleep(5); -+ -+ if(state->tuner_id == TS2022_ID){ -+ msleep(2); -+ value = m88ds3103_tuner_readreg(state, 0x26); -+ capCode = value & 0x3f; -+ -+ m88ds3103_tuner_writereg(state, 0x41, 0x09); -+ -+ m88ds3103_tuner_writereg(state, 0x51, 0x1b); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x04); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ -+ msleep(2); -+ value = m88ds3103_tuner_readreg(state, 0x26); -+ value &= 0x3f; -+ value = (capCode + value) / 2; -+ -+ value = value | 0x80; -+ m88ds3103_tuner_writereg(state, 0x25, value); -+ m88ds3103_tuner_writereg(state, 0x27, 0x30); -+ -+ m88ds3103_tuner_writereg(state, 0x08, 0x09); -+ } -+ -+ /* Set the BB gain */ -+ m88ds3103_tuner_writereg(state, 0x51, 0x1e); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x01); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ if(state->tuner_id == TS2020_ID){ -+ if(RFgain == 15){ -+ msleep(40); -+ value = m88ds3103_tuner_readreg(state, 0x21); -+ value &= 0x0f; -+ if(value < 3){ -+ m88ds3103_tuner_writereg(state, 0x60, 0x61); -+ m88ds3103_tuner_writereg(state, 0x51, 0x17); -+ m88ds3103_tuner_writereg(state, 0x51, 0x1f); -+ m88ds3103_tuner_writereg(state, 0x50, 0x08); -+ m88ds3103_tuner_writereg(state, 0x50, 0x00); -+ } -+ } -+ } -+ msleep(60); -+ -+ offset_khz = (ndiv - ndiv % 2 + 1024) * MT_FE_CRYSTAL_KHZ -+ / (6 + 8) / (div4 + 1) / 2 - realFreq; -+ -+ m88ds3103_demod_connect(fe, offset_khz+lpf_offset_KHz); -+ -+ for (i = 0; i < 30 ; i++) { -+ m88ds3103_read_status(fe, &status); -+ if (status & FE_HAS_LOCK){ -+ break; -+ } -+ msleep(20); -+ } -+ -+ if((status & FE_HAS_LOCK) == 0){ -+ state->delivery_system = (state->delivery_system == SYS_DVBS) ? SYS_DVBS2 : SYS_DVBS; -+ m88ds3103_demod_connect(fe, offset_khz); -+ -+ for (i = 0; i < 30 ; i++) { -+ m88ds3103_read_status(fe, &status); -+ if (status & FE_HAS_LOCK){ -+ break; -+ } -+ msleep(20); -+ } -+ } -+ -+ if (status & FE_HAS_LOCK){ -+ if(state->config->ci_mode == 2) -+ m88ds3103_set_clock_ratio(state); -+ if(state->config->start_ctrl){ -+ if(state->first_lock == 0){ -+ state->config->start_ctrl(fe); -+ state->first_lock = 1; -+ } -+ } -+ } -+ -+ return 0; -+} -+ -+static int m88ds3103_tune(struct dvb_frontend *fe, -+ bool re_tune, -+ unsigned int mode_flags, -+ unsigned int *delay, -+ fe_status_t *status) -+{ -+ *delay = HZ / 5; -+ -+ dprintk("%s() ", __func__); -+ dprintk("re_tune = %d\n", re_tune); -+ -+ if (re_tune) { -+ int ret = m88ds3103_set_frontend(fe); -+ if (ret) -+ return ret; -+ } -+ -+ return m88ds3103_read_status(fe, status); -+} -+ -+static enum dvbfe_algo m88ds3103_get_algo(struct dvb_frontend *fe) -+{ -+ return DVBFE_ALGO_HW; -+} -+ -+ /* -+ * Power config will reset and load initial firmware if required -+ */ -+static int m88ds3103_initilaze(struct dvb_frontend *fe) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ int ret; -+ -+ dprintk("%s()\n", __func__); -+ /* hard reset */ -+ m88ds3103_writereg(state, 0x07, 0x80); -+ m88ds3103_writereg(state, 0x07, 0x00); -+ msleep(1); -+ -+ m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08)); -+ msleep(1); -+ -+ if(state->tuner_id == TS2020_ID){ -+ /* TS2020 init */ -+ m88ds3103_tuner_writereg(state, 0x42, 0x73); -+ msleep(2); -+ m88ds3103_tuner_writereg(state, 0x05, 0x01); -+ m88ds3103_tuner_writereg(state, 0x62, 0xb5); -+ m88ds3103_tuner_writereg(state, 0x07, 0x02); -+ m88ds3103_tuner_writereg(state, 0x08, 0x01); -+ } -+ else if(state->tuner_id == TS2022_ID){ -+ /* TS2022 init */ -+ m88ds3103_tuner_writereg(state, 0x62, 0x6c); -+ msleep(2); -+ m88ds3103_tuner_writereg(state, 0x42, 0x6c); -+ msleep(2); -+ m88ds3103_tuner_writereg(state, 0x7d, 0x9d); -+ m88ds3103_tuner_writereg(state, 0x7c, 0x9a); -+ m88ds3103_tuner_writereg(state, 0x7a, 0x76); -+ -+ m88ds3103_tuner_writereg(state, 0x3b, 0x01); -+ m88ds3103_tuner_writereg(state, 0x63, 0x88); -+ -+ m88ds3103_tuner_writereg(state, 0x61, 0x85); -+ m88ds3103_tuner_writereg(state, 0x22, 0x30); -+ m88ds3103_tuner_writereg(state, 0x30, 0x40); -+ m88ds3103_tuner_writereg(state, 0x20, 0x23); -+ m88ds3103_tuner_writereg(state, 0x24, 0x02); -+ m88ds3103_tuner_writereg(state, 0x12, 0xa0); -+ } -+ -+ if(state->demod_id == DS3103_ID){ -+ m88ds3103_writereg(state, 0x07, 0xe0); -+ m88ds3103_writereg(state, 0x07, 0x00); -+ msleep(1); -+ } -+ m88ds3103_writereg(state, 0xb2, 0x01); -+ -+ /* Load the firmware if required */ -+ ret = m88ds3103_load_firmware(fe); -+ if (ret != 0){ -+ printk(KERN_ERR "%s: Unable initialize firmware\n", __func__); -+ return ret; -+ } -+ if(state->demod_id == DS3103_ID){ -+ m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d)); -+ m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30)); -+ } -+ -+ return 0; -+} -+ -+/* -+ * Initialise or wake up device -+ */ -+static int m88ds3103_initfe(struct dvb_frontend *fe) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ u8 val; -+ -+ dprintk("%s()\n", __func__); -+ -+ /* 1st step to wake up demod */ -+ m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08)); -+ m88ds3103_writereg(state, 0x04, 0xfe & m88ds3103_readreg(state, 0x04)); -+ m88ds3103_writereg(state, 0x23, 0xef & m88ds3103_readreg(state, 0x23)); -+ -+ /* 2nd step to wake up tuner */ -+ val = m88ds3103_tuner_readreg(state, 0x00) & 0xff; -+ if((val & 0x01) == 0){ -+ m88ds3103_tuner_writereg(state, 0x00, 0x01); -+ msleep(50); -+ } -+ m88ds3103_tuner_writereg(state, 0x00, 0x03); -+ msleep(50); -+ -+ return 0; -+} -+ -+/* Put device to sleep */ -+static int m88ds3103_sleep(struct dvb_frontend *fe) -+{ -+ struct m88ds3103_state *state = fe->demodulator_priv; -+ -+ dprintk("%s()\n", __func__); -+ -+ /* 1st step to sleep tuner */ -+ m88ds3103_tuner_writereg(state, 0x00, 0x00); -+ -+ /* 2nd step to sleep demod */ -+ m88ds3103_writereg(state, 0x08, 0xfe & m88ds3103_readreg(state, 0x08)); -+ m88ds3103_writereg(state, 0x04, 0x01 | m88ds3103_readreg(state, 0x04)); -+ m88ds3103_writereg(state, 0x23, 0x10 | m88ds3103_readreg(state, 0x23)); -+ -+ -+ return 0; -+} -+ -+static struct dvb_frontend_ops m88ds3103_ops = { -+ .delsys = { SYS_DVBS, SYS_DVBS2}, -+ .info = { -+ .name = "Montage DS3103/TS2022", -+ .type = FE_QPSK, -+ .frequency_min = 950000, -+ .frequency_max = 2150000, -+ .frequency_stepsize = 1011, /* kHz for QPSK frontends */ -+ .frequency_tolerance = 5000, -+ .symbol_rate_min = 1000000, -+ .symbol_rate_max = 45000000, -+ .caps = FE_CAN_INVERSION_AUTO | -+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | -+ FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | -+ FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | -+ FE_CAN_2G_MODULATION | -+ FE_CAN_QPSK | FE_CAN_RECOVER -+ }, -+ -+ .release = m88ds3103_release, -+ -+ .init = m88ds3103_initfe, -+ .sleep = m88ds3103_sleep, -+ .read_status = m88ds3103_read_status, -+ .read_ber = m88ds3103_read_ber, -+ .read_signal_strength = m88ds3103_read_signal_strength, -+ .read_snr = m88ds3103_read_snr, -+ .read_ucblocks = m88ds3103_read_ucblocks, -+ .set_tone = m88ds3103_set_tone, -+ .set_voltage = m88ds3103_set_voltage, -+ .diseqc_send_master_cmd = m88ds3103_send_diseqc_msg, -+ .diseqc_send_burst = m88ds3103_diseqc_send_burst, -+ .get_frontend_algo = m88ds3103_get_algo, -+ .tune = m88ds3103_tune, -+ .set_frontend = m88ds3103_set_frontend, -+}; -+ -+MODULE_DESCRIPTION("DVB Frontend module for Montage DS3103/TS2022 hardware"); -+MODULE_AUTHOR("Max nibble"); -+MODULE_LICENSE("GPL"); -diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.h v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.h ---- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.h 1970-01-01 01:00:00.000000000 +0100 -+++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.h 2012-11-24 13:34:43.716679774 +0100 -@@ -0,0 +1,53 @@ -+/* -+ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver -+ -+ 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, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#ifndef M88DS3103_H -+#define M88DS3103_H -+ -+#include <linux/dvb/frontend.h> -+ -+struct m88ds3103_config { -+ /* the demodulator's i2c address */ -+ u8 demod_address; -+ u8 ci_mode; -+ u8 pin_ctrl; -+ u8 ts_mode; /* 0: Parallel, 1: Serial */ -+ -+ /* Set device param to start dma */ -+ int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); -+ /* Start to transfer data */ -+ int (*start_ctrl)(struct dvb_frontend *fe); -+ /* Set LNB voltage */ -+ int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); -+}; -+ -+#if defined(CONFIG_DVB_M88DS3103) || \ -+ (defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE)) -+extern struct dvb_frontend *m88ds3103_attach( -+ const struct m88ds3103_config *config, -+ struct i2c_adapter *i2c); -+#else -+static inline struct dvb_frontend *m88ds3103_attach( -+ const struct m88ds3103_config *config, -+ struct i2c_adapter *i2c) -+{ -+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -+ return NULL; -+} -+#endif /* CONFIG_DVB_M88DS3103 */ -+#endif /* M88DS3103_H */ -diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103_priv.h v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103_priv.h ---- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103_priv.h 1970-01-01 01:00:00.000000000 +0100 -+++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103_priv.h 2012-11-24 13:34:43.716679774 +0100 -@@ -0,0 +1,403 @@ -+/* -+ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver -+ -+ 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, write to the Free Software -+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#ifndef M88DS3103_PRIV_H -+#define M88DS3103_PRIV_H -+ -+#define FW_DOWN_SIZE 32 -+#define FW_DOWN_LOOP (8192/FW_DOWN_SIZE) -+#define DS3103_DEFAULT_FIRMWARE "dvb-fe-ds3103.fw" -+#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds300x.fw" -+#define MT_FE_MCLK_KHZ 96000 /* in kHz */ -+#define MT_FE_CRYSTAL_KHZ 27000 /* in kHz */ -+#define FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz 3000 -+#define DS3000_ID 0x3000 -+#define DS3103_ID 0x3103 -+#define TS2020_ID 0x2020 -+#define TS2022_ID 0x2022 -+#define UNKNOW_ID 0x0000 -+ -+struct m88ds3103_state { -+ struct i2c_adapter *i2c; -+ const struct m88ds3103_config *config; -+ -+ struct dvb_frontend frontend; -+ -+ u32 preBer; -+ u8 skip_fw_load; -+ u8 first_lock; /* The first time of signal lock */ -+ u16 demod_id; /* demod chip type */ -+ u16 tuner_id; /* tuner chip type */ -+ fe_delivery_system_t delivery_system; -+}; -+ -+/* For M88DS3103 demod dvbs mode.*/ -+static u8 ds3103_dvbs_init_tab[] = { -+ 0x23, 0x07, -+ 0x08, 0x03, -+ 0x0c, 0x02, -+ 0x21, 0x54, -+ 0x25, 0x82, -+ 0x27, 0x31, -+ 0x30, 0x08, -+ 0x31, 0x40, -+ 0x32, 0x32, -+ 0x33, 0x35, -+ 0x35, 0xff, -+ 0x3a, 0x00, -+ 0x37, 0x10, -+ 0x38, 0x10, -+ 0x39, 0x02, -+ 0x42, 0x60, -+ 0x4a, 0x80, -+ 0x4b, 0x04, -+ 0x4d, 0x91, -+ 0x5d, 0xc8, -+ 0x50, 0x36, -+ 0x51, 0x36, -+ 0x52, 0x36, -+ 0x53, 0x36, -+ 0x63, 0x0f, -+ 0x64, 0x30, -+ 0x65, 0x40, -+ 0x68, 0x26, -+ 0x69, 0x4c, -+ 0x70, 0x20, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x40, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x60, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x80, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0xa0, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x1f, -+ 0x76, 0x38, -+ 0x77, 0xa6, -+ 0x78, 0x0c, -+ 0x79, 0x80, -+ 0x7f, 0x14, -+ 0x7c, 0x00, -+ 0xae, 0x82, -+ 0x80, 0x64, -+ 0x81, 0x66, -+ 0x82, 0x44, -+ 0x85, 0x04, -+ 0xcd, 0xf4, -+ 0x90, 0x33, -+ 0xa0, 0x44, -+ 0xc0, 0x08, -+ 0xc3, 0x10, -+ 0xc4, 0x08, -+ 0xc5, 0xf0, -+ 0xc6, 0xff, -+ 0xc7, 0x00, -+ 0xc8, 0x1a, -+ 0xc9, 0x80, -+ 0xe0, 0xf8, -+ 0xe6, 0x8b, -+ 0xd0, 0x40, -+ 0xf8, 0x20, -+ 0xfa, 0x0f, -+ 0x00, 0x00, -+ 0xbd, 0x01, -+ 0xb8, 0x00, -+}; -+/* For M88DS3103 demod dvbs2 mode.*/ -+static u8 ds3103_dvbs2_init_tab[] = { -+ 0x23, 0x07, -+ 0x08, 0x07, -+ 0x0c, 0x02, -+ 0x21, 0x54, -+ 0x25, 0x82, -+ 0x27, 0x31, -+ 0x30, 0x08, -+ 0x32, 0x32, -+ 0x33, 0x35, -+ 0x35, 0xff, -+ 0x3a, 0x00, -+ 0x37, 0x10, -+ 0x38, 0x10, -+ 0x39, 0x02, -+ 0x42, 0x60, -+ 0x4a, 0x80, -+ 0x4b, 0x04, -+ 0x4d, 0x91, -+ 0x5d, 0xc8, -+ 0x50, 0x36, -+ 0x51, 0x36, -+ 0x52, 0x36, -+ 0x53, 0x36, -+ 0x63, 0x0f, -+ 0x64, 0x10, -+ 0x65, 0x20, -+ 0x68, 0x46, -+ 0x69, 0xcd, -+ 0x70, 0x20, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x40, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x60, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x80, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0xa0, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x1f, -+ 0x76, 0x38, -+ 0x77, 0xa6, -+ 0x78, 0x0c, -+ 0x79, 0x80, -+ 0x7f, 0x14, -+ 0x85, 0x08, -+ 0xcd, 0xf4, -+ 0x90, 0x33, -+ 0x86, 0x00, -+ 0x87, 0x0f, -+ 0x89, 0x00, -+ 0x8b, 0x44, -+ 0x8c, 0x66, -+ 0x9d, 0xc1, -+ 0x8a, 0x10, -+ 0xad, 0x40, -+ 0xa0, 0x44, -+ 0xc0, 0x08, -+ 0xc1, 0x10, -+ 0xc2, 0x08, -+ 0xc3, 0x10, -+ 0xc4, 0x08, -+ 0xc5, 0xf0, -+ 0xc6, 0xff, -+ 0xc7, 0x00, -+ 0xc8, 0x1a, -+ 0xc9, 0x80, -+ 0xca, 0x23, -+ 0xcb, 0x24, -+ 0xcc, 0xf4, -+ 0xce, 0x74, -+ 0x00, 0x00, -+ 0xbd, 0x01, -+ 0xb8, 0x00, -+}; -+ -+/* For M88DS3000 demod dvbs mode.*/ -+static u8 ds3000_dvbs_init_tab[] = { -+ 0x23, 0x05, -+ 0x08, 0x03, -+ 0x0c, 0x02, -+ 0x21, 0x54, -+ 0x25, 0x82, -+ 0x27, 0x31, -+ 0x30, 0x08, -+ 0x31, 0x40, -+ 0x32, 0x32, -+ 0x33, 0x35, -+ 0x35, 0xff, -+ 0x3a, 0x00, -+ 0x37, 0x10, -+ 0x38, 0x10, -+ 0x39, 0x02, -+ 0x42, 0x60, -+ 0x4a, 0x40, -+ 0x4b, 0x04, -+ 0x4d, 0x91, -+ 0x5d, 0xc8, -+ 0x50, 0x77, -+ 0x51, 0x77, -+ 0x52, 0x36, -+ 0x53, 0x36, -+ 0x56, 0x01, -+ 0x63, 0x47, -+ 0x64, 0x30, -+ 0x65, 0x40, -+ 0x68, 0x26, -+ 0x69, 0x4c, -+ 0x70, 0x20, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x40, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x60, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x80, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0xa0, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x1f, -+ 0x76, 0x00, -+ 0x77, 0xd1, -+ 0x78, 0x0c, -+ 0x79, 0x80, -+ 0x7f, 0x04, -+ 0x7c, 0x00, -+ 0x80, 0x86, -+ 0x81, 0xa6, -+ 0x85, 0x04, -+ 0xcd, 0xf4, -+ 0x90, 0x33, -+ 0xa0, 0x44, -+ 0xc0, 0x18, -+ 0xc3, 0x10, -+ 0xc4, 0x08, -+ 0xc5, 0x80, -+ 0xc6, 0x80, -+ 0xc7, 0x0a, -+ 0xc8, 0x1a, -+ 0xc9, 0x80, -+ 0xfe, 0xb6, -+ 0xe0, 0xf8, -+ 0xe6, 0x8b, -+ 0xd0, 0x40, -+ 0xf8, 0x20, -+ 0xfa, 0x0f, -+ 0xad, 0x20, -+ 0xae, 0x07, -+ 0xb8, 0x00, -+}; -+ -+/* For M88DS3000 demod dvbs2 mode.*/ -+static u8 ds3000_dvbs2_init_tab[] = { -+ 0x23, 0x0f, -+ 0x08, 0x07, -+ 0x0c, 0x02, -+ 0x21, 0x54, -+ 0x25, 0x82, -+ 0x27, 0x31, -+ 0x30, 0x08, -+ 0x31, 0x32, -+ 0x32, 0x32, -+ 0x33, 0x35, -+ 0x35, 0xff, -+ 0x3a, 0x00, -+ 0x37, 0x10, -+ 0x38, 0x10, -+ 0x39, 0x02, -+ 0x42, 0x60, -+ 0x4a, 0x80, -+ 0x4b, 0x04, -+ 0x4d, 0x91, -+ 0x5d, 0x88, -+ 0x50, 0x36, -+ 0x51, 0x36, -+ 0x52, 0x36, -+ 0x53, 0x36, -+ 0x63, 0x60, -+ 0x64, 0x10, -+ 0x65, 0x10, -+ 0x68, 0x04, -+ 0x69, 0x29, -+ 0x70, 0x20, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x40, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x60, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x80, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0xa0, -+ 0x71, 0x70, -+ 0x72, 0x04, -+ 0x73, 0x00, -+ 0x70, 0x1f, -+ 0xa0, 0x44, -+ 0xc0, 0x08, -+ 0xc1, 0x10, -+ 0xc2, 0x08, -+ 0xc3, 0x10, -+ 0xc4, 0x08, -+ 0xc5, 0xf0, -+ 0xc6, 0xf0, -+ 0xc7, 0x0a, -+ 0xc8, 0x1a, -+ 0xc9, 0x80, -+ 0xca, 0x23, -+ 0xcb, 0x24, -+ 0xce, 0x74, -+ 0x56, 0x01, -+ 0x90, 0x03, -+ 0x76, 0x80, -+ 0x77, 0x42, -+ 0x78, 0x0a, -+ 0x79, 0x80, -+ 0xad, 0x40, -+ 0xae, 0x07, -+ 0x7f, 0xd4, -+ 0x7c, 0x00, -+ 0x80, 0xa8, -+ 0x81, 0xda, -+ 0x7c, 0x01, -+ 0x80, 0xda, -+ 0x81, 0xec, -+ 0x7c, 0x02, -+ 0x80, 0xca, -+ 0x81, 0xeb, -+ 0x7c, 0x03, -+ 0x80, 0xba, -+ 0x81, 0xdb, -+ 0x85, 0x08, -+ 0x86, 0x00, -+ 0x87, 0x02, -+ 0x89, 0x80, -+ 0x8b, 0x44, -+ 0x8c, 0xaa, -+ 0x8a, 0x10, -+ 0xba, 0x00, -+ 0xf5, 0x04, -+ 0xd2, 0x32, -+ 0xb8, 0x00, -+}; -+ -+#endif /* M88DS3103_PRIV_H */ -diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Makefile v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Makefile ---- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Makefile 2012-08-17 05:45:27.000000000 +0200 -+++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Makefile 2012-11-24 13:34:43.716679774 +0100 -@@ -102,4 +102,7 @@ - obj-$(CONFIG_DVB_RTL2832) += rtl2832.o - obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o - obj-$(CONFIG_DVB_AF9033) += af9033.o -+obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o -+ -+ - -diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/Makefile v4l-dvb-20120916/linux/drivers/media/rc/keymaps/Makefile ---- v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/Makefile 2012-05-21 05:45:41.000000000 +0200 -+++ v4l-dvb-20120916/linux/drivers/media/rc/keymaps/Makefile 2012-11-24 13:34:43.716679774 +0100 -@@ -27,6 +27,7 @@ - rc-dm1105-nec.o \ - rc-dntv-live-dvb-t.o \ - rc-dntv-live-dvbt-pro.o \ -+ rc-dvbsky.o \ - rc-em-terratec.o \ - rc-encore-enltv2.o \ - rc-encore-enltv.o \ -diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/rc-dvbsky.c v4l-dvb-20120916/linux/drivers/media/rc/keymaps/rc-dvbsky.c ---- v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/rc-dvbsky.c 1970-01-01 01:00:00.000000000 +0100 -+++ v4l-dvb-20120916/linux/drivers/media/rc/keymaps/rc-dvbsky.c 2012-11-24 13:34:43.716679774 +0100 -@@ -0,0 +1,78 @@ -+/* rc-dvbsky.c - Keytable for Dvbsky Remote Controllers -+ * -+ * keymap imported from ir-keymaps.c -+ * -+ * -+ * Copyright (c) 2010-2011 by Mauro Carvalho Chehab mchehab@redhat.com -+ * -+ * 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. -+ */ -+ -+#include <media/rc-map.h> -+#include <linux/module.h> -+/* -+ * This table contains the complete RC5 code, instead of just the data part -+ */ -+ -+static struct rc_map_table rc5_dvbsky[] = { -+ { 0x0000, KEY_0 }, -+ { 0x0001, KEY_1 }, -+ { 0x0002, KEY_2 }, -+ { 0x0003, KEY_3 }, -+ { 0x0004, KEY_4 }, -+ { 0x0005, KEY_5 }, -+ { 0x0006, KEY_6 }, -+ { 0x0007, KEY_7 }, -+ { 0x0008, KEY_8 }, -+ { 0x0009, KEY_9 }, -+ { 0x000a, KEY_MUTE }, -+ { 0x000d, KEY_OK }, -+ { 0x000b, KEY_STOP }, -+ { 0x000c, KEY_EXIT }, -+ { 0x000e, KEY_CAMERA }, /*Snap shot*/ -+ { 0x000f, KEY_SUBTITLE }, /*PIP*/ -+ { 0x0010, KEY_VOLUMEUP }, -+ { 0x0011, KEY_VOLUMEDOWN }, -+ { 0x0012, KEY_FAVORITES }, -+ { 0x0013, KEY_LIST }, /*Info*/ -+ { 0x0016, KEY_PAUSE }, -+ { 0x0017, KEY_PLAY }, -+ { 0x001f, KEY_RECORD }, -+ { 0x0020, KEY_CHANNELDOWN }, -+ { 0x0021, KEY_CHANNELUP }, -+ { 0x0025, KEY_POWER2 }, -+ { 0x0026, KEY_REWIND }, -+ { 0x0027, KEY_FASTFORWARD }, -+ { 0x0029, KEY_LAST }, -+ { 0x002b, KEY_MENU }, -+ { 0x002c, KEY_EPG }, -+ { 0x002d, KEY_ZOOM }, -+}; -+ -+static struct rc_map_list rc5_dvbsky_map = { -+ .map = { -+ .scan = rc5_dvbsky, -+ .size = ARRAY_SIZE(rc5_dvbsky), -+ .rc_type = RC_TYPE_RC5, -+ .name = RC_MAP_DVBSKY, -+ } -+}; -+ -+static int __init init_rc_map_rc5_dvbsky(void) -+{ -+ return rc_map_register(&rc5_dvbsky_map); -+} -+ -+static void __exit exit_rc_map_rc5_dvbsky(void) -+{ -+ rc_map_unregister(&rc5_dvbsky_map); -+} -+ -+module_init(init_rc_map_rc5_dvbsky) -+module_exit(exit_rc_map_rc5_dvbsky) -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Mauro Carvalho Chehab mchehab@redhat.com"); -diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/dw2102.c v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/dw2102.c ---- v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/dw2102.c 2012-08-14 05:45:22.000000000 +0200 -+++ v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/dw2102.c 2012-11-24 15:44:13.269971182 +0100 -@@ -3,6 +3,7 @@ - * TeVii S600, S630, S650, S660, S480, - * Prof 1100, 7500, - * Geniatech SU3000 Cards -+ * Bestunar US683x HD, DVBsky S860, S960 USB - * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by) - * - * This program is free software; you can redistribute it and/or modify it -@@ -19,6 +20,7 @@ - #include "stb6000.h" - #include "eds1547.h" - #include "cx24116.h" -+#include "m88ds3103.h" - #include "tda1002x.h" - #include "mt312.h" - #include "zl10039.h" -@@ -786,7 +788,7 @@ - struct su3000_state *state = (struct su3000_state *)d->priv; - u8 obuf[] = {0xde, 0}; - -- info("%s: %d, initialized %d\n", __func__, i, state->initialized); -+ info("%s: %d, initialized %d", __func__, i, state->initialized); - - if (i && !state->initialized) { - state->initialized = 1; -@@ -824,7 +826,40 @@ - else - mac[i] = ibuf[0]; - -- debug_dump(mac, 6, printk); -+ debug_dump(mac, 6, deb_xfer); -+ } -+ -+ return 0; -+} -+ -+static int dvbsky_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -+{ -+ int i; -+ u8 obuf[] = { 0x1e, 0x00 }; -+ u8 ibuf[] = { 0 }; -+ struct i2c_msg msg[] = { -+ { -+ .addr = 0x51, -+ .flags = 0, -+ .buf = obuf, -+ .len = 2, -+ }, { -+ .addr = 0x51, -+ .flags = I2C_M_RD, -+ .buf = ibuf, -+ .len = 1, -+ -+ } -+ }; -+ -+ for (i = 0; i < 6; i++) { -+ obuf[1] = i; -+ if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) -+ break; -+ else -+ mac[i] = ibuf[0]; -+ -+ debug_dump(mac, 6, deb_xfer); - } - - return 0; -@@ -835,7 +870,7 @@ - struct dvb_usb_device_description **desc, - int *cold) - { -- info("%s\n", __func__); -+ info("%s", __func__); - - *cold = 0; - return 0; -@@ -878,6 +913,43 @@ - return 0; - } - -+static int bstusb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -+{ -+ -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ -+ u8 obuf[3] = { 0xe, 0x80, 0 }; -+ u8 ibuf[] = { 0 }; -+ -+ //info("US6830: %s!", __func__); -+ -+ if (voltage == SEC_VOLTAGE_OFF) -+ obuf[2] = 0; -+ else -+ obuf[2] = 1; -+ -+ if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ return 0; -+} -+ -+static int bstusb_restart(struct dvb_frontend *fe) -+{ -+ -+ struct dvb_usb_adapter *udev_adap = -+ (struct dvb_usb_adapter *)(fe->dvb->priv); -+ -+ u8 obuf[3] = { 0x36, 3, 0 }; -+ u8 ibuf[] = { 0 }; -+ -+ if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 0, 0) < 0) -+ err("command 0x36 transfer failed."); -+ -+ return 0; -+} -+ - static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) - { - static u8 led_off[] = { 0 }; -@@ -983,6 +1055,24 @@ - .ci_mode = 1, - }; - -+static struct m88ds3103_config US6830_ds3103_config = { -+ .demod_address = 0x68, -+ .ci_mode = 1, -+ .pin_ctrl = 0x83, -+ .ts_mode = 0, -+ .start_ctrl = bstusb_restart, -+ .set_voltage = bstusb_set_voltage, -+}; -+ -+static struct m88ds3103_config US6832_ds3103_config = { -+ .demod_address = 0x68, -+ .ci_mode = 1, -+ .pin_ctrl = 0x80, -+ .ts_mode = 0, -+ .start_ctrl = bstusb_restart, -+ .set_voltage = bstusb_set_voltage, -+}; -+ - static int dw2104_frontend_attach(struct dvb_usb_adapter *d) - { - struct dvb_tuner_ops *tuner_ops = NULL; -@@ -1000,7 +1090,7 @@ - tuner_ops->set_bandwidth = stb6100_set_bandw; - tuner_ops->get_bandwidth = stb6100_get_bandw; - d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; -- info("Attached STV0900+STB6100!\n"); -+ info("Attached STV0900+STB6100!"); - return 0; - } - } -@@ -1014,7 +1104,7 @@ - &dw2104_stv6110_config, - &d->dev->i2c_adap)) { - d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; -- info("Attached STV0900+STV6110A!\n"); -+ info("Attached STV0900+STV6110A!"); - return 0; - } - } -@@ -1025,7 +1115,7 @@ - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { - d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; -- info("Attached cx24116!\n"); -+ info("Attached cx24116!"); - return 0; - } - } -@@ -1034,7 +1124,7 @@ - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { - d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; -- info("Attached DS3000!\n"); -+ info("Attached DS3000!"); - return 0; - } - -@@ -1053,7 +1143,7 @@ - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { - d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; -- info("Attached si21xx!\n"); -+ info("Attached si21xx!"); - return 0; - } - } -@@ -1065,7 +1155,7 @@ - if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, - &d->dev->i2c_adap)) { - d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; -- info("Attached stv0288!\n"); -+ info("Attached stv0288!"); - return 0; - } - } -@@ -1077,7 +1167,7 @@ - &d->dev->i2c_adap); - if (d->fe_adap[0].fe != NULL) { - d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; -- info("Attached stv0299!\n"); -+ info("Attached stv0299!"); - return 0; - } - } -@@ -1089,7 +1179,7 @@ - d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config, - &d->dev->i2c_adap, 0x48); - if (d->fe_adap[0].fe != NULL) { -- info("Attached tda10023!\n"); -+ info("Attached tda10023!"); - return 0; - } - return -EIO; -@@ -1103,7 +1193,7 @@ - if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60, - &d->dev->i2c_adap)) { - d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; -- info("Attached zl100313+zl10039!\n"); -+ info("Attached zl100313+zl10039!"); - return 0; - } - } -@@ -1128,7 +1218,7 @@ - - dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); - -- info("Attached stv0288+stb6000!\n"); -+ info("Attached stv0288+stb6000!"); - - return 0; - -@@ -1150,7 +1240,7 @@ - - dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); - -- info("Attached ds3000+ds2020!\n"); -+ info("Attached ds3000+ds2020!"); - - return 0; - } -@@ -1168,7 +1258,7 @@ - - dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); - -- info("Attached STV0900+STB6100A!\n"); -+ info("Attached STV0900+STB6100A!"); - - return 0; - } -@@ -1205,7 +1295,88 @@ - if (d->fe_adap[0].fe == NULL) - return -EIO; - -- info("Attached DS3000!\n"); -+ info("Attached DS3000!"); -+ -+ return 0; -+} -+ -+static int US6830_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ u8 obuf[3] = { 0xe, 0x04, 1 }; -+ u8 ibuf[] = { 0 }; -+ -+ info("US6830: %s!\n", __func__); -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ obuf[0] = 0xe; -+ obuf[1] = 0x83; -+ obuf[2] = 0; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ msleep(20); -+ -+ obuf[0] = 0xe; -+ obuf[1] = 0x83; -+ obuf[2] = 1; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ obuf[0] = 0x51; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) -+ err("command 0x51 transfer failed."); -+ -+ d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6830_ds3103_config, -+ &d->dev->i2c_adap); -+ if (d->fe_adap[0].fe == NULL) -+ return -EIO; -+ -+ info("Attached M88DS3103!"); -+ -+ return 0; -+} -+ -+static int US6832_frontend_attach(struct dvb_usb_adapter *d) -+{ -+ u8 obuf[3] = { 0xe, 0x04, 1 }; -+ u8 ibuf[] = { 0 }; -+ -+ info("US6832: %s!", __func__); -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ obuf[0] = 0xe; -+ obuf[1] = 0x83; -+ obuf[2] = 0; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ msleep(20); -+ obuf[0] = 0xe; -+ obuf[1] = 0x83; -+ obuf[2] = 1; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) -+ err("command 0x0e transfer failed."); -+ -+ obuf[0] = 0x51; -+ -+ if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) -+ err("command 0x51 transfer failed."); -+ -+ d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6832_ds3103_config, -+ &d->dev->i2c_adap); -+ if (d->fe_adap[0].fe == NULL) -+ return -EIO; -+ -+ info("Attached M88DS3103!"); - - return 0; - } -@@ -1447,6 +1618,9 @@ - TEVII_S480_1, - TEVII_S480_2, - X3M_SPC1400HD, -+ BST_US6830HD, -+ BST_US6831HD, -+ BST_US6832HD, - }; - - static struct usb_device_id dw2102_table[] = { -@@ -1465,6 +1639,9 @@ - [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, - [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, - [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)}, -+ [BST_US6830HD] = {USB_DEVICE(0x0572, 0x6830)}, -+ [BST_US6831HD] = {USB_DEVICE(0x0572, 0x6831)}, -+ [BST_US6832HD] = {USB_DEVICE(0x0572, 0x6832)}, - { } - }; - -@@ -1870,6 +2047,106 @@ - } - }; - -+static struct dvb_usb_device_properties US6830_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .size_of_priv = sizeof(struct su3000_state), -+ .power_ctrl = su3000_power_ctrl, -+ .num_adapters = 1, -+ .identify_state = su3000_identify_state, -+ .i2c_algo = &su3000_i2c_algo, -+ -+ .rc.legacy = { -+ .rc_map_table = rc_map_su3000_table, -+ .rc_map_size = ARRAY_SIZE(rc_map_su3000_table), -+ .rc_interval = 150, -+ .rc_query = dw2102_rc_query, -+ }, -+ -+ .read_mac_address = dvbsky_read_mac_address, -+ -+ .generic_bulk_ctrl_endpoint = 0x01, -+ -+ .adapter = { -+ { -+ .num_frontends = 1, -+ .fe = {{ -+ .streaming_ctrl = su3000_streaming_ctrl, -+ .frontend_attach = US6830_frontend_attach, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ } -+ }}, -+ } -+ }, -+ .num_device_descs = 2, -+ .devices = { -+ { "Bestunar US6830 HD", -+ { &dw2102_table[BST_US6830HD], NULL }, -+ { NULL }, -+ }, -+ { "Bestunar US6831 HD", -+ { &dw2102_table[BST_US6831HD], NULL }, -+ { NULL }, -+ }, -+ } -+}; -+ -+static struct dvb_usb_device_properties US6832_properties = { -+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, -+ .usb_ctrl = DEVICE_SPECIFIC, -+ .size_of_priv = sizeof(struct su3000_state), -+ .power_ctrl = su3000_power_ctrl, -+ .num_adapters = 1, -+ .identify_state = su3000_identify_state, -+ .i2c_algo = &su3000_i2c_algo, -+ -+ .rc.legacy = { -+ .rc_map_table = rc_map_su3000_table, -+ .rc_map_size = ARRAY_SIZE(rc_map_su3000_table), -+ .rc_interval = 150, -+ .rc_query = dw2102_rc_query, -+ }, -+ -+ .read_mac_address = dvbsky_read_mac_address, -+ -+ .generic_bulk_ctrl_endpoint = 0x01, -+ -+ .adapter = { -+ { -+ .num_frontends = 1, -+ .fe = {{ -+ .streaming_ctrl = su3000_streaming_ctrl, -+ .frontend_attach = US6832_frontend_attach, -+ .stream = { -+ .type = USB_BULK, -+ .count = 8, -+ .endpoint = 0x82, -+ .u = { -+ .bulk = { -+ .buffersize = 4096, -+ } -+ } -+ } -+ }}, -+ } -+ }, -+ .num_device_descs = 1, -+ .devices = { -+ { "Bestunar US6832 HD", -+ { &dw2102_table[BST_US6832HD], NULL }, -+ { NULL }, -+ }, -+ } -+}; -+ - static int dw2102_probe(struct usb_interface *intf, - const struct usb_device_id *id) - { -@@ -1926,6 +2203,10 @@ - 0 == dvb_usb_device_init(intf, p7500, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &su3000_properties, -+ THIS_MODULE, NULL, adapter_nr) || -+ 0 == dvb_usb_device_init(intf, &US6830_properties, -+ THIS_MODULE, NULL, adapter_nr) || -+ 0 == dvb_usb_device_init(intf, &US6832_properties, - THIS_MODULE, NULL, adapter_nr)) - return 0; - -diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/Kconfig v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/Kconfig ---- v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/Kconfig 2012-08-22 05:45:23.000000000 +0200 -+++ v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/Kconfig 2012-11-24 13:34:43.716679774 +0100 -@@ -1,3 +1,4 @@ -++ select DVB_M88DS3103 if !DVB_FE_CUSTOMISE - config DVB_USB - tristate "Support for various USB DVB devices" - depends on DVB_CORE && USB && I2C && RC_CORE -@@ -261,6 +262,7 @@ - select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT - select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT -+ select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT - select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT - select DVB_SI21XX if MEDIA_SUBDRV_AUTOSELECT - select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT -diff -Naur v4l-dvb-20120916.ORG/linux/include/media/rc-map.h v4l-dvb-20120916/linux/include/media/rc-map.h ---- v4l-dvb-20120916.ORG/linux/include/media/rc-map.h 2012-05-21 05:45:41.000000000 +0200 -+++ v4l-dvb-20120916/linux/include/media/rc-map.h 2012-11-24 13:34:43.716679774 +0100 -@@ -86,6 +86,7 @@ - #define RC_MAP_DM1105_NEC "rc-dm1105-nec" - #define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro" - #define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t" -+#define RC_MAP_DVBSKY "rc-dvbsky" - #define RC_MAP_EMPTY "rc-empty" - #define RC_MAP_EM_TERRATEC "rc-em-terratec" - #define RC_MAP_ENCORE_ENLTV2 "rc-encore-enltv2" diff --git a/src/patches/v4l-dvb_rtl28xx_add_usb_ids.patch b/src/patches/v4l-dvb_rtl28xx_add_usb_ids.patch deleted file mode 100644 index 1dd649a..0000000 --- a/src/patches/v4l-dvb_rtl28xx_add_usb_ids.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -Naur v4l-dvb-20120916.org/linux/drivers/media/usb/dvb-usb-v2/rtl28xxu.c v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb-v2/rtl28xxu.c ---- v4l-dvb-20120916.org/linux/drivers/media/usb/dvb-usb-v2/rtl28xxu.c 2012-09-16 05:46:03.000000000 +0200 -+++ v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb-v2/rtl28xxu.c 2012-09-19 20:03:04.538168193 +0200 -@@ -1228,6 +1228,10 @@ - &rtl2832u_props, "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", NULL) }, - { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK, - &rtl2832u_props, "NOXON DAB/DAB+ USB dongle", NULL) }, -+ { DVB_USB_DEVICE(0x1d19, 0x1101, -+ &rtl2832u_props, "DK DVB-T USB dongle", NULL) }, -+ { DVB_USB_DEVICE(0x1f4d, 0xc803, -+ &rtl2832u_props, "Trekstor DVB-T DAB FM USB dongle", NULL) }, - { } - }; - MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table); diff --git a/src/patches/v4l-dvb_rtl28xx_commented_usb_clear_halt.patch b/src/patches/v4l-dvb_rtl28xx_commented_usb_clear_halt.patch deleted file mode 100644 index 8fb8bc4..0000000 --- a/src/patches/v4l-dvb_rtl28xx_commented_usb_clear_halt.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur v4l-dvb-20120916.org/linux/drivers/media/usb/dvb-usb-v2/rtl28xxu.c v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb-v2/rtl28xxu.c ---- v4l-dvb-20120916.org/linux/drivers/media/usb/dvb-usb-v2/rtl28xxu.c 2012-09-16 05:46:03.000000000 +0200 -+++ v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb-v2/rtl28xxu.c 2012-10-24 13:48:13.113373414 +0200 -@@ -836,7 +836,7 @@ - if (onoff) { - buf[0] = 0x00; - buf[1] = 0x00; -- usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x81)); -+// usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x81)); - } else { - buf[0] = 0x10; /* stall EPA */ - buf[1] = 0x02; /* reset EPA */ diff --git a/src/patches/v4l-dvb_usbv2_dont_report_pidfilter_fail.patch b/src/patches/v4l-dvb_usbv2_dont_report_pidfilter_fail.patch deleted file mode 100644 index 4b16125..0000000 --- a/src/patches/v4l-dvb_usbv2_dont_report_pidfilter_fail.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff -Naur v4l-dvb-20120916.org/linux/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c ---- v4l-dvb-20120916.org/linux/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c 2012-08-16 05:45:24.000000000 +0200 -+++ v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c 2012-10-24 13:53:35.636726448 +0200 -@@ -287,9 +287,9 @@ - ret = adap->props->pid_filter(adap, dvbdmxfeed->index, - dvbdmxfeed->pid, (count == 1) ? 1 : 0); - if (ret < 0) -- dev_err(&d->udev->dev, "%s: pid_filter() " \ -- "failed=%d\n", KBUILD_MODNAME, -- ret); -+// dev_err(&d->udev->dev, "%s: pid_filter() " \ -+// "failed=%d\n", KBUILD_MODNAME, -+// ret); - - /* start feeding if it is first pid */ - if (adap->feed_count == 1 && count == 1) { diff --git a/src/patches/vdr-1.6.0-gcc44-fixes.patch b/src/patches/vdr-1.6.0-gcc44-fixes.patch deleted file mode 100644 index d8841d8..0000000 --- a/src/patches/vdr-1.6.0-gcc44-fixes.patch +++ /dev/null @@ -1,62 +0,0 @@ -Index: vdr-1.6.0/recording.c -=================================================================== ---- vdr-1.6.0.orig/recording.c -+++ vdr-1.6.0/recording.c -@@ -509,8 +509,8 @@ cRecording::cRecording(cTimer *Timer, co - Utf8Strn0Cpy(SubtitleBuffer, Subtitle, MAX_SUBTITLE_LENGTH); - Subtitle = SubtitleBuffer; - } -- char *macroTITLE = strstr(Timer->File(), TIMERMACRO_TITLE); -- char *macroEPISODE = strstr(Timer->File(), TIMERMACRO_EPISODE); -+ const char *macroTITLE = strstr(Timer->File(), TIMERMACRO_TITLE); -+ const char *macroEPISODE = strstr(Timer->File(), TIMERMACRO_EPISODE); - if (macroTITLE || macroEPISODE) { - name = strdup(Timer->File()); - name = strreplace(name, TIMERMACRO_TITLE, Title); -@@ -551,7 +551,7 @@ cRecording::cRecording(const char *FileN - sortBuffer = NULL; - fileName = strdup(FileName); - FileName += strlen(VideoDirectory) + 1; -- char *p = strrchr(FileName, '/'); -+ const char *p = strrchr(FileName, '/'); - - name = NULL; - info = new cRecordingInfo; -@@ -1022,7 +1022,8 @@ void cRecordings::DelByName(const char * - if (recording) { - cThreadLock DeletedRecordingsLock(&DeletedRecordings); - Del(recording, false); -- char *ext = strrchr(recording->FileName(), '.'); -+ // wtf? -+ char *ext = strrchr(const_cast<char*>(recording->FileName()), '.'); - if (ext) { - strncpy(ext, DELEXT, strlen(ext)); - recording->fileSizeMB = DirSizeMB(recording->FileName()); -Index: vdr-1.6.0/svdrp.c -=================================================================== ---- vdr-1.6.0.orig/svdrp.c -+++ vdr-1.6.0/svdrp.c -@@ -736,7 +736,7 @@ void cSVDRP::CmdGRAB(const char *Option) - char *strtok_next; - FileName = strtok_r(p, delim, &strtok_next); - // image type: -- char *Extension = strrchr(FileName, '.'); -+ const char *Extension = strrchr(FileName, '.'); - if (Extension) { - if (strcasecmp(Extension, ".jpg") == 0 || strcasecmp(Extension, ".jpeg") == 0) - Jpeg = true; -@@ -796,12 +796,12 @@ void cSVDRP::CmdGRAB(const char *Option) - if (FileName) { - if (grabImageDir) { - cString s; -- char *slash = strrchr(FileName, '/'); -+ char *slash = strrchr(const_cast<char*>(FileName), '/'); - if (!slash) { - s = AddDirectory(grabImageDir, FileName); - FileName = s; - } -- slash = strrchr(FileName, '/'); // there definitely is one -+ slash = strrchr(const_cast<char*>(FileName), '/'); // there definitely is one - *slash = 0; - char *r = realpath(FileName, RealFileName); - *slash = '/'; diff --git a/src/patches/vdr-plugin-epgsearch-gcc44.patch b/src/patches/vdr-plugin-epgsearch-gcc44.patch deleted file mode 100644 index 2a92a3b..0000000 --- a/src/patches/vdr-plugin-epgsearch-gcc44.patch +++ /dev/null @@ -1,78 +0,0 @@ -diff -urNad vdr-plugin-epgsearch-0.9.24~/epgsearchsvdrp.c vdr-plugin-epgsearch-0.9.24/epgsearchsvdrp.c ---- vdr-plugin-epgsearch-0.9.24~/epgsearchsvdrp.c 2008-04-13 20:53:44.000000000 +0200 -+++ vdr-plugin-epgsearch-0.9.24/epgsearchsvdrp.c 2009-10-26 20:27:07.000000000 +0100 -@@ -742,12 +742,13 @@ - { - if (*Option) - { -- char* pipePos = strchr(Option, '|'); -+ const char* pipePos = strchr(Option, '|'); - if (pipePos) - { -- *pipePos = 0; -- const char* oldName = Option; -- const char* newName = pipePos+1; -+ int index = pipePos - Option; -+ char* oldName = strdup(Option); -+ *(oldName + index) = 0; -+ const char* newName = oldName + index + 1; - if (strlen(oldName) > 0 && strlen(newName) > 0) - { - cChannelGroup *changrp = ChannelGroups.GetGroupByName(Option); -@@ -769,15 +770,18 @@ - } - ChannelGroups.Save(); - SearchExts.Save(); -+ free(oldName); - return cString::sprintf("renamed channel group '%s' to '%s'", oldName, newName); - - } - else - { -+ free(oldName); - ReplyCode = 901; - return cString::sprintf("channel group '%s' not defined", Option); - } - } -+ free(oldName); - } - ReplyCode = 901; - return cString("Error in channel group parameters"); -diff -urNad vdr-plugin-epgsearch-0.9.24~/epgsearchtools.c vdr-plugin-epgsearch-0.9.24/epgsearchtools.c ---- vdr-plugin-epgsearch-0.9.24~/epgsearchtools.c 2008-04-13 20:53:42.000000000 +0200 -+++ vdr-plugin-epgsearch-0.9.24/epgsearchtools.c 2009-10-26 20:27:07.000000000 +0100 -@@ -743,7 +743,7 @@ - while(tmp) - { - // extract a single line -- char* lf = strchr(tmp, '\n'); -+ const char* lf = strchr(tmp, '\n'); - char* line = NULL; - if (lf) - line = strndup(tmp, lf-tmp); -diff -urNad vdr-plugin-epgsearch-0.9.24~/menu_dirselect.c vdr-plugin-epgsearch-0.9.24/menu_dirselect.c ---- vdr-plugin-epgsearch-0.9.24~/menu_dirselect.c 2008-04-13 20:53:44.000000000 +0200 -+++ vdr-plugin-epgsearch-0.9.24/menu_dirselect.c 2009-10-26 20:27:07.000000000 +0100 -@@ -83,7 +83,7 @@ - return 1; - do - { -- char* pos = strchr(szDir, '~'); -+ const char* pos = strchr(szDir, '~'); - if (pos) - { - iLevel++; -diff -urNad vdr-plugin-epgsearch-0.9.24~/searchtimer_thread.c vdr-plugin-epgsearch-0.9.24/searchtimer_thread.c ---- vdr-plugin-epgsearch-0.9.24~/searchtimer_thread.c 2008-04-28 18:22:31.000000000 +0200 -+++ vdr-plugin-epgsearch-0.9.24/searchtimer_thread.c 2009-10-26 20:27:28.000000000 +0100 -@@ -565,8 +565,8 @@ - if (!isempty(aux)) - { - tmpaux = strdup(aux); -- char* begin = strstr(aux, "<epgsearch>"); -- char* end = strstr(aux, "</epgsearch>"); -+ const char* begin = strstr(aux, "<epgsearch>"); -+ const char* end = strstr(aux, "</epgsearch>"); - if (begin && end) - { - if (begin == aux) strcpy(tmpaux, ""); else strn0cpy(tmpaux, aux, begin-aux+1);
hooks/post-receive -- IPFire 2.x development tree