From b3f5e2b2a9153bf4a55c79f44d8a983487f7b55c Mon Sep 17 00:00:00 2001 From: Arne Fitzenreiter Date: Sun, 30 Nov 2014 01:45:15 +0100 Subject: [PATCH] remove more enused patches. --- lfs/cyrus-imapd | 1 - lfs/udev | 1 - ...d-2.6-reneg-ciphers-altnames-nosslv2.patch | 452 - ...drivers-3.8-1-u-kref_get_unless_zero.patch | 38 - ...ompat-wireless-2.6.34-usbnet_compile.patch | 28 - ...at-wireless-2.6.39_kfifo_module_info.patch | 14 - ...reless-3.5-build_ath5k_only_with_pci.patch | 16 - .../compat-wireless-3.5-libertas_uap.patch | 5080 ----- ...eless_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 - .../net-tools-1.60-kernel_headers-2.patch | 51 - .../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 - ...ython-satsolver-only-python-bindings.patch | 27 - ...on-satsover-fix-building-without-rpm.patch | 37 - .../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 - ...dvb_rtl28xx_commented_usb_clear_halt.patch | 12 - ...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 diff --git a/lfs/cyrus-imapd b/lfs/cyrus-imapd index 8f74c5a305..2a826cd703 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 fdf8bf2968..15dae817b2 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 9c874c88f3..0000000000 --- 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 -+ - #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 1930d80fe2..0000000000 --- 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 -- * 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 - * 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 36146fb4dc..0000000000 --- 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 eb5d2806b6..0000000000 --- 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 - #include - -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Stefani Seibold "); -+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 2e82157aaf..0000000000 --- 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 633bb67720..0000000000 --- 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) -+#include -+#else -+#include -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) -+#include -+#endif -+ -+/* Net header files */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "uap_drv.h" -+#include "uap_fw.h" -+ -+#include -+#include -+#include -+#include -+#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 -+ -+/** 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 -+#include -+#include -+#include -+ -+#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 210a58c6a7..0000000000 --- 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 -X-Patchwork-Id: 173968 -Message-Id: <1343631141.2626.13293.camel@edumazet-glaptop> -To: David Miller -Cc: netdev , Anton Mich - -From: Eric Dumazet - -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 -Signed-off-by: Eric Dumazet - ---- -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 44edb41d57..0000000000 --- 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 293c20c0de..0000000000 --- a/src/patches/glibc-arm-dont-use-swp.patch +++ /dev/null @@ -1,305 +0,0 @@ -commit 1ba025a9a21eda65d8c36cc0dbb51d214a3ebb1a -Author: Daniel Jacobowitz -Date: Mon Jun 2 01:57:03 2008 +0000 - - 2008-06-01 Paul Brook - Zack Weinberg - Daniel Jacobowitz - - * 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 -- -- .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 -+#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 -- --#include -- -- .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 -+#include -+#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 d2bb95921c..0000000000 --- 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 -+ -+ * netboot/cs89x0.c: Fix license violation. -+ * netboot/cs89x0.h: Likewise. -+ -+2008-04-10 Pavel Roskin -+ -+ * configure.ac: Always use "_cv_" in cache variables for -+ compatibility with Autoconf 2.62. -+ -+2008-03-28 Robert Millan -+ -+ 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 -+ -+ * 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 -+ -+ * stage2/iso9660.h: Remove unnecessary packed attributes. -+ -+2007-02-22 Robert Millan -+ -+ * util/mkbimage: Update my email address, and remove my name from -+ some places where unnecessary credit is given. -+ -+2006-09-10 Pavel Roskin -+ -+ * 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 -+ -+ * 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 -+ -+ * 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 -+ -+ * lib/device.c (write_to_partition): /dev/ataraid/ and /dev/rd/ -+ partitions have a "p" prefix. Add it. -+ -+2006-06-24 Robert Millan -+ -+ * lib/device.c (get_i2o_disk_name): New function. -+ (init_device_map) [__linux__]: Add support for I2O devices. -+ -+2006-05-02 Pavel Roskin -+ -+ * 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 -+ -+ * 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 -+ -+ * grub/asmstub.c (get_diskinfo): Optimize sysctl routine. -+ -+2006-04-20 Robert Millan -+ -+ 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 -+ -+ * docs/multiboot.texi: Correct the offset of address -+ fields. Reported by Jeroen Dekkers. -+ -+2006-03-21 Yoshinori K. Okuji -+ -+ * stage2/builtins.c (setup_func): Specify the size of DEVICE to -+ grub_strncat instead of a strange number 256. Reported by Vitaly -+ Fertman . -+ -+2005-09-29 Yoshinori K. Okuji -+ -+ * 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 -+ -+ * 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 - - * 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/}. -+ -+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} .= < - --@dircategory Kernel --@direntry --* Multiboot Specification: (multiboot). Multiboot Specification. --@end direntry -+Copyright @copyright{} 1995,96 Erich Stefan Boleyn - --@ifinfo --Copyright @copyright{} 1995, 96 Bryan Ford --Copyright @copyright{} 1995, 96 Erich Stefan Boleyn --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 --Copyright @copyright{} 1995, 96 Erich Stefan Boleyn --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 - #include - #include -+#include - - #ifdef __linux__ - # include /* ioctl */ -@@ -55,6 +56,10 @@ - # endif /* ! BLKFLSBUF */ - #endif /* __linux__ */ - -+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__) -+# include -+#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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __linux__ -+# include /* ioctl */ -+# if !defined(__GLIBC__) || \ -+ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) -+/* Maybe libc doesn't have large file support. */ -+# include /* _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 -+#include -+#include -+#include -+ -+/* 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 - #include -+#include - - 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define WITHOUT_LIBC_STUBS 1 -+#include -+#include -+ -+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 .\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 - #include - -+#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 */ -+ { -+ 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/dp -+ -+ It currently supports up to 3 controllers, 10 logical volumes -+ and 10 partitions -+ -+ Code gratuitously copied from DAC960 above. -+ Horms 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/dp -+ -+ It currently supports up to 3 controllers, 10 logical volumes -+ and 15 partitions -+ -+ Code gratuitously copied from DAC960 above. -+ Piotr Roszatycki -+ */ -+ { -+ 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 on -+ 18 March 2008 this file is now licensed under GPL Version 2. -+ -+ From: Russ Nelson -+ 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 on -+ 18 March 2008 this file is now licensed under GPL Version 2. -+ -+ From: Russ Nelson -+ 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 -+#endif -+ -+#include -+#include -+#include -+ -+#ifdef SUPPORT_NETBOOT -+# define GRUB 1 -+# include -+#endif -+ -+#ifdef SUPPORT_SERIAL -+# include -+# include -+#endif -+ -+#ifdef GRUB_UTIL -+# include -+#else /* ! GRUB_UTIL */ -+# include -+# include -+#endif /* ! GRUB_UTIL */ -+ -+#ifdef USE_MD5_PASSWORDS -+# include -+#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 -+#include -+ -+#ifdef SUPPORT_HERCULES -+# include -+#endif -+ -+#ifdef SUPPORT_SERIAL -+# include -+#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 - #include -+#include - - #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 based -+ * on a patch by Paulo César Pereira de Andrade -+ */ -+/* -+ * 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 -+#include -+#include -+ -+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 . -@@ -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 . -+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 -+#include -+ -+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 - Yury V. Umanets - Yuri Zaporogets -+Vitaly Fertman -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 <$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 <$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: 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 <$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 <&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 <$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 <$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 --# C) 2001,2002,2003 Robert Millan -+# C) 2001,2002,2003 Robert Millan - - - # 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 . --Copyright (c) 2001,2002 Robert Millan . - GPLed." - - version="mkbimage $version_number - --Written by Thierry Laronde and Robert Millan. -+Written by Thierry Laronde. - - Copyright (c) 2001,2002,2003 Thierry Laronde . --Copyright (c) 2001,2002,2003 Robert Millan . - - 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 c075dc7b51..0000000000 --- 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 9272c37a6b..0000000000 --- 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 60531851d9..0000000000 --- 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 -- -+/* - _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 ca3dd40131..0000000000 --- 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 - #include - #include -+#include - - #include - #include - diff --git a/src/patches/libsigc++-gcc43.patch b/src/patches/libsigc++-gcc43.patch deleted file mode 100644 index 528f21e1ff..0000000000 --- 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 emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot slot_type; -- typedef slot_list slot_list_type; -+ typedef sigc::slot_list 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 emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot slot_type; -- typedef slot_list slot_list_type; -+ typedef sigc::slot_list 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 emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot slot_type; -- typedef slot_list slot_list_type; -+ typedef sigc::slot_list 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 emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot slot_type; -- typedef slot_list slot_list_type; -+ typedef sigc::slot_list 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 emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot slot_type; -- typedef slot_list slot_list_type; -+ typedef sigc::slot_list 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 emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot slot_type; -- typedef slot_list slot_list_type; -+ typedef sigc::slot_list 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 emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot slot_type; -- typedef slot_list slot_list_type; -+ typedef sigc::slot_list 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 emitter_type; - typedef typename emitter_type::result_type result_type; - typedef slot slot_type; -- typedef slot_list slot_list_type; -+ typedef sigc::slot_list 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 -+#include -+#include - #include - - 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 795d0a370e..0000000000 --- a/src/patches/nasm-0.98.39-security_fix-1.patch +++ /dev/null @@ -1,21 +0,0 @@ -Submitted By: Ken Moffat -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 c88153761e..0000000000 --- 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 - - #if HAVE_AFDECnet -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) - #include - #endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -+#include -+#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 - #include - #include -+#include - #include - #include - #include -@@ -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 82d85097a7..0000000000 --- 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 -+ -+ -+#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 , -+ xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait, -+ Ethan Sommer, Justin Levandoski. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) -+#include -+#include -+#endif -+#include -+#include -+#include -+#include -+ -+#include "regexp/regexp.c" -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Matthew Strait , Ethan Sommer "); -+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 0913f9a5cb..0000000000 --- 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 --# 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 --#include -+#if defined(__linux__) -+# include -+# define HAVE_CRYPTODEV_NAME -+#else -+# include -+#endif - #include - #include - #include -@@ -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 590c21dd19..0000000000 --- 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 43257d5d3d..0000000000 --- a/src/patches/pciutils-2.1.99-gcc4.patch +++ /dev/null @@ -1,17 +0,0 @@ -Patch by Robert Scheck 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 62b57f0875..0000000000 --- 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 789dee5d92..0000000000 --- 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 <$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 14f9f5e873..0000000000 --- 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 87e45b44ce..0000000000 --- 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 56fbff3da5..0000000000 --- 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 --#include --#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 --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 19ca22eafa..0000000000 --- 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 9dceebc5e8..0000000000 --- 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 36905d00c3..0000000000 --- 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 68e276735e..0000000000 --- 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 31dde459cb..0000000000 --- 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 - #include - -+#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 a065493e29..0000000000 --- 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 86916f6488..0000000000 --- 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 5bb4db24b0..0000000000 --- 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 77072cea60..0000000000 --- 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 fcc5009dd5..0000000000 --- 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 e3ac8d2614..0000000000 --- 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 nibble -+ Copyright (C) 2010 Montage Technology -+ 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 -+#include -+#include -+#include -+#include -+#include -+ -+#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 -+ -+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 -+ * -+ * 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 -+#include -+/* -+ * 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 "); -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 1dd649a81a..0000000000 --- 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 8fb8bc4e3b..0000000000 --- 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 4b161255b3..0000000000 --- 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 d8841d8b08..0000000000 --- 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(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(FileName), '/'); - if (!slash) { - s = AddDirectory(grabImageDir, FileName); - FileName = s; - } -- slash = strrchr(FileName, '/'); // there definitely is one -+ slash = strrchr(const_cast(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 2a92a3b178..0000000000 --- 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, ""); -- char* end = strstr(aux, ""); -+ const char* begin = strstr(aux, ""); -+ const char* end = strstr(aux, ""); - if (begin && end) - { - if (begin == aux) strcpy(tmpaux, ""); else strn0cpy(tmpaux, aux, begin-aux+1); -- 2.39.2