]> git.ipfire.org Git - people/dweismueller/ipfire-2.x.git/commitdiff
remove more enused patches.
authorArne Fitzenreiter <arne_f@ipfire.org>
Sun, 30 Nov 2014 00:45:15 +0000 (01:45 +0100)
committerArne Fitzenreiter <arne_f@ipfire.org>
Sun, 30 Nov 2014 00:45:15 +0000 (01:45 +0100)
45 files changed:
lfs/cyrus-imapd
lfs/udev
src/patches/Pound-2.6-reneg-ciphers-altnames-nosslv2.patch [deleted file]
src/patches/compat-drivers-3.8-1-u-kref_get_unless_zero.patch [deleted file]
src/patches/compat-wireless-2.6.34-usbnet_compile.patch [deleted file]
src/patches/compat-wireless-2.6.39_kfifo_module_info.patch [deleted file]
src/patches/compat-wireless-3.5-build_ath5k_only_with_pci.patch [deleted file]
src/patches/compat-wireless-3.5-libertas_uap.patch [deleted file]
src/patches/compat-wireless_codel-avoid-a-nul-rec_inv_sqrt.patch [deleted file]
src/patches/dhcp-3.1_linux3.patch [deleted file]
src/patches/glibc-arm-dont-use-swp.patch [deleted file]
src/patches/grub-gentoo-14.patch [deleted file]
src/patches/lcd4linux-scaletext-dpf.patch [deleted file]
src/patches/libcap-1.10-shared.patch [deleted file]
src/patches/libcap-1.10-syscall.patch [deleted file]
src/patches/libnl-1.1-ULONG_MAX.patch [deleted file]
src/patches/libsigc++-gcc43.patch [deleted file]
src/patches/lzo-2.06-CVE-2014-4607.patch [changed mode: 0755->0644]
src/patches/nasm-0.98.39-security_fix-1.patch [deleted file]
src/patches/net-tools-1.60-kernel_headers-2.patch [deleted file]
src/patches/netfilter_layer7_2.22_kernel3.0.patch [deleted file]
src/patches/openssl-0.9.8n-cryptodev.diff [deleted file]
src/patches/pciutils-2.1.10-scan.patch [deleted file]
src/patches/pciutils-2.1.99-gcc4.patch [deleted file]
src/patches/pciutils-2.2.1-idpath.patch [deleted file]
src/patches/pciutils-2.2.3-multilib.patch [deleted file]
src/patches/pciutils-2.2.3-sata.patch [deleted file]
src/patches/pciutils-devicetype.patch [deleted file]
src/patches/pciutils-havepread.patch [deleted file]
src/patches/pciutils-strip.patch [deleted file]
src/patches/pound-2.6.patch [deleted file]
src/patches/python-satsolver-only-python-bindings.patch [deleted file]
src/patches/python-satsover-fix-building-without-rpm.patch [deleted file]
src/patches/qemu-0.14.1_missing_ATFCWD_hack.patch [deleted file]
src/patches/r8101_add_missing_pciids.patch [deleted file]
src/patches/r8169_add_missing_pciids.patch [deleted file]
src/patches/sudo-1.6.8p12-envvar_fix-1.patch [deleted file]
src/patches/udev-125-ext4_wo_journal.patch [deleted file]
src/patches/udev-141_no_netif_rename.patch [deleted file]
src/patches/v4l-dvb_bestunar_us638x.patch [deleted file]
src/patches/v4l-dvb_rtl28xx_add_usb_ids.patch [deleted file]
src/patches/v4l-dvb_rtl28xx_commented_usb_clear_halt.patch [deleted file]
src/patches/v4l-dvb_usbv2_dont_report_pidfilter_fail.patch [deleted file]
src/patches/vdr-1.6.0-gcc44-fixes.patch [deleted file]
src/patches/vdr-plugin-epgsearch-gcc44.patch [deleted file]

index 8f74c5a305f8e37376fb3f16d2f655510da85c4e..2a826cd7039b7996feab4e4ce242189739167f6b 100644 (file)
@@ -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 \
index fdf8bf296876d4e03df7cc30910cab281de1cc93..15dae817b2b35dd6d02f7ccbfb80be7dbdb487b1 100644 (file)
--- 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 (file)
index 9c874c8..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-diff -Naur Pound-2.6.orig/config.c Pound-2.6.reneg-ciphers-altnames-nosslv2/config.c
---- Pound-2.6.orig/config.c    2011-12-28 14:57:45.000000000 +0100
-+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/config.c  2012-02-15 21:49:39.000000000 +0100
-@@ -31,6 +31,8 @@
- #include    "pound.h"
-+#include    <openssl/x509v3.h>
-+
- #ifdef MISS_FACILITYNAMES
- /* This is lifted verbatim from the Linux sys/syslog.h */
-@@ -76,7 +78,7 @@
- static regex_t  Err414, Err500, Err501, Err503, MaxRequest, HeadRemove, RewriteLocation, RewriteDestination;
- static regex_t  Service, ServiceName, URL, HeadRequire, HeadDeny, BackEnd, Emergency, Priority, HAport, HAportAddr;
- static regex_t  Redirect, RedirectN, TimeOut, Session, Type, TTL, ID, DynScale;
--static regex_t  ClientCert, AddHeader, Ciphers, CAlist, VerifyList, CRLlist, NoHTTPS11;
-+static regex_t  ClientCert, AddHeader, DisableSSLv2, SSLAllowClientRenegotiation, SSLHonorCipherOrder, Ciphers, CAlist, VerifyList, CRLlist, NoHTTPS11;
- static regex_t  Grace, Include, ConnTO, IgnoreCase, HTTPS, HTTPSCert, Disabled, Threads, CNName;
- static regmatch_t   matches[5];
-@@ -167,6 +169,53 @@
-     }
- }
-+unsigned char **
-+get_subjectaltnames(X509 *x509, unsigned int *count)
-+{
-+    *count = 0;
-+    unsigned int local_count = 0;
-+    unsigned char **result = NULL;
-+
-+    STACK_OF(GENERAL_NAME) *san_stack = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);     
-+
-+    unsigned char *temp[sk_GENERAL_NAME_num(san_stack)];
-+
-+    GENERAL_NAME *name = NULL;
-+    while(sk_GENERAL_NAME_num(san_stack) > 0)
-+    {
-+        name = sk_GENERAL_NAME_pop(san_stack);
-+
-+        switch(name->type)
-+        {
-+            case GEN_DNS:
-+                temp[local_count] = strndup(ASN1_STRING_data(name->d.dNSName), ASN1_STRING_length(name->d.dNSName)+1);
-+                if(temp[local_count] == NULL) { conf_err("out of memory"); }
-+                local_count++;
-+                break;
-+            default:
-+              logmsg(LOG_INFO, "unsupported subjectAltName type encountered: %i", name->type);
-+        }
-+
-+        GENERAL_NAME_free(name);
-+    }
-+
-+    result = (unsigned char**)malloc(sizeof(unsigned char*)*local_count);
-+    if(result == NULL) { conf_err("out of memory"); }
-+    int i;
-+    for(i = 0;i < local_count; i++)
-+    {
-+        result[i] = strndup(temp[i], strlen(temp[i])+1);
-+        if(result[i] == NULL) { conf_err("out of memory"); }
-+
-+        free(temp[i]);
-+    }
-+    *count = local_count;
-+
-+    sk_GENERAL_NAME_pop_free(san_stack, GENERAL_NAME_free);
-+
-+    return result;
-+}
-+
- /*
-  * parse a back-end
-  */
-@@ -289,9 +338,12 @@
-         } else if(!regexec(&HTTPS, lin, 4, matches, 0)) {
-             if((res->ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
-                 conf_err("SSL_CTX_new failed - aborted");
-+            SSL_CTX_set_app_data(res->ctx, res);
-             SSL_CTX_set_verify(res->ctx, SSL_VERIFY_NONE, NULL);
-             SSL_CTX_set_mode(res->ctx, SSL_MODE_AUTO_RETRY);
-             SSL_CTX_set_options(res->ctx, SSL_OP_ALL);
-+            SSL_CTX_clear_options(res->ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
-+            SSL_CTX_clear_options(res->ctx, SSL_OP_LEGACY_SERVER_CONNECT);
-             sprintf(lin, "%d-Pound-%ld", getpid(), random());
-             SSL_CTX_set_session_id_context(res->ctx, (unsigned char *)lin, strlen(lin));
-             SSL_CTX_set_tmp_rsa_callback(res->ctx, RSA_tmp_callback);
-@@ -299,6 +351,7 @@
-         } else if(!regexec(&HTTPSCert, lin, 4, matches, 0)) {
-             if((res->ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
-                 conf_err("SSL_CTX_new failed - aborted");
-+            SSL_CTX_set_app_data(res->ctx, res);
-             lin[matches[1].rm_eo] = '\0';
-             if(SSL_CTX_use_certificate_chain_file(res->ctx, lin + matches[1].rm_so) != 1)
-                 conf_err("SSL_CTX_use_certificate_chain_file failed - aborted");
-@@ -309,6 +362,8 @@
-             SSL_CTX_set_verify(res->ctx, SSL_VERIFY_NONE, NULL);
-             SSL_CTX_set_mode(res->ctx, SSL_MODE_AUTO_RETRY);
-             SSL_CTX_set_options(res->ctx, SSL_OP_ALL);
-+            SSL_CTX_clear_options(res->ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
-+            SSL_CTX_clear_options(res->ctx, SSL_OP_LEGACY_SERVER_CONNECT);
-             sprintf(lin, "%d-Pound-%ld", getpid(), random());
-             SSL_CTX_set_session_id_context(res->ctx, (unsigned char *)lin, strlen(lin));
-             SSL_CTX_set_tmp_rsa_callback(res->ctx, RSA_tmp_callback);
-@@ -805,13 +860,23 @@
-     /* logmsg(LOG_DEBUG, "Received SSL SNI Header for servername %s", servername); */
-     SSL_set_SSL_CTX(ssl, NULL);
--    for(pc = ctx; pc; pc = pc->next)
-+    for(pc = ctx; pc; pc = pc->next) {
-         if(fnmatch(pc->server_name, server_name, 0) == 0) {
-             /* logmsg(LOG_DEBUG, "Found cert for %s", servername); */
-             SSL_set_SSL_CTX(ssl, pc->ctx);
-             return SSL_TLSEXT_ERR_OK;
-         }
--
-+        else if(pc->subjectAltNameCount > 0 && pc->subjectAltNames != NULL) {
-+            int i;
-+            for(i = 0; i < pc->subjectAltNameCount; i++) {
-+                if(fnmatch(pc->subjectAltNames[i], server_name, 0) == 0) {
-+                    SSL_set_SSL_CTX(ssl, pc->ctx);
-+                    return SSL_TLSEXT_ERR_OK;
-+                }
-+            }
-+        }
-+    }
-+    
-     /* logmsg(LOG_DEBUG, "No match for %s, default used", server_name); */
-     SSL_set_SSL_CTX(ssl, ctx->ctx);
-     return SSL_TLSEXT_ERR_OK;
-@@ -829,11 +894,15 @@
-     SERVICE     *svc;
-     MATCHER     *m;
-     int         has_addr, has_port, has_other;
-+    long      ssl_op_enable, ssl_op_disable;
-     struct hostent      *host;
-     struct sockaddr_in  in;
-     struct sockaddr_in6 in6;
-     POUND_CTX   *pc;
-+    ssl_op_enable = SSL_OP_ALL;
-+    ssl_op_disable = SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | SSL_OP_LEGACY_SERVER_CONNECT;
-+
-     if((res = (LISTENER *)malloc(sizeof(LISTENER))) == NULL)
-         conf_err("ListenHTTPS config: out of memory - aborted");
-     memset(res, 0, sizeof(LISTENER));
-@@ -844,6 +913,8 @@
-     res->err500 = "An internal server error occurred. Please try again later.";
-     res->err501 = "This method may not be used.";
-     res->err503 = "The service is not available. Please try again later.";
-+    res->allow_client_reneg = 0;
-+    res->disable_ssl_v2 = 0;
-     res->log_level = log_level;
-     if(regcomp(&res->verb, xhttp[0], REG_ICASE | REG_NEWLINE | REG_EXTENDED))
-         conf_err("xHTTP bad default pattern - aborted");
-@@ -959,6 +1030,9 @@
-             fclose(fcert);
-             memset(server_name, '\0', MAXBUF);
-             X509_NAME_oneline(X509_get_subject_name(x509), server_name, MAXBUF - 1);
-+            pc->subjectAltNameCount = 0;
-+            pc->subjectAltNames = NULL;
-+            pc->subjectAltNames = get_subjectaltnames(x509, &(pc->subjectAltNameCount));
-             X509_free(x509);
-             if(!regexec(&CNName, server_name, 4, matches, 0)) {
-                 server_name[matches[1].rm_eo] = '\0';
-@@ -1029,6 +1103,25 @@
-                 strcat(res->add_head, "\r\n");
-                 strcat(res->add_head, lin + matches[1].rm_so);
-             }
-+      } else if(!regexec(&DisableSSLv2, lin, 4, matches, 0)) {
-+          res->disable_ssl_v2 = 1;
-+        } else if(!regexec(&SSLAllowClientRenegotiation, lin, 4, matches, 0)) {
-+            res->allow_client_reneg = atoi(lin + matches[1].rm_so);
-+            if (res->allow_client_reneg == 2) {
-+                ssl_op_enable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
-+                ssl_op_disable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
-+            } else {
-+                ssl_op_disable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
-+                ssl_op_enable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
-+            }
-+        } else if(!regexec(&SSLHonorCipherOrder, lin, 4, matches, 0)) {
-+            if (atoi(lin + matches[1].rm_so)) {
-+                ssl_op_enable |= SSL_OP_CIPHER_SERVER_PREFERENCE;
-+                ssl_op_disable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
-+            } else {
-+                ssl_op_disable |= SSL_OP_CIPHER_SERVER_PREFERENCE;
-+                ssl_op_enable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
-+            }
-         } else if(!regexec(&Ciphers, lin, 4, matches, 0)) {
-             has_other = 1;
-             if(res->ctx == NULL)
-@@ -1105,12 +1198,19 @@
-                 conf_err("ListenHTTPS: can't set SNI callback");
- #endif
-             for(pc = res->ctx; pc; pc = pc->next) {
-+                SSL_CTX_set_app_data(pc->ctx, res);
-                 SSL_CTX_set_mode(pc->ctx, SSL_MODE_AUTO_RETRY);
--                SSL_CTX_set_options(pc->ctx, SSL_OP_ALL);
-+                SSL_CTX_set_options(pc->ctx, ssl_op_enable);
-+                SSL_CTX_clear_options(pc->ctx, ssl_op_disable);
-+              if (res->disable_ssl_v2 == 1)
-+              {
-+                  SSL_CTX_set_options(pc->ctx, SSL_OP_NO_SSLv2);
-+              }
-                 sprintf(lin, "%d-Pound-%ld", getpid(), random());
-                 SSL_CTX_set_session_id_context(pc->ctx, (unsigned char *)lin, strlen(lin));
-                 SSL_CTX_set_tmp_rsa_callback(pc->ctx, RSA_tmp_callback);
-                 SSL_CTX_set_tmp_dh_callback(pc->ctx, DH_tmp_callback);
-+                SSL_CTX_set_info_callback(pc->ctx, SSLINFO_callback);
-             }
-             return res;
-         } else {
-@@ -1305,6 +1405,9 @@
-     || regcomp(&DynScale, "^[ \t]*DynScale[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
-     || regcomp(&ClientCert, "^[ \t]*ClientCert[ \t]+([0-3])[ \t]+([1-9])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
-     || regcomp(&AddHeader, "^[ \t]*AddHeader[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
-+    || regcomp(&SSLAllowClientRenegotiation, "^[ \t]*SSLAllowClientRenegotiation[ \t]+([012])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
-+    || regcomp(&DisableSSLv2, "^[ \t]*DisableSSLv2[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
-+    || regcomp(&SSLHonorCipherOrder, "^[ \t]*SSLHonorCipherOrder[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
-     || regcomp(&Ciphers, "^[ \t]*Ciphers[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
-     || regcomp(&CAlist, "^[ \t]*CAlist[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
-     || regcomp(&VerifyList, "^[ \t]*VerifyList[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
-@@ -1463,6 +1566,9 @@
-     regfree(&DynScale);
-     regfree(&ClientCert);
-     regfree(&AddHeader);
-+    regfree(&SSLAllowClientRenegotiation);
-+    regfree(&DisableSSLv2);
-+    regfree(&SSLHonorCipherOrder);
-     regfree(&Ciphers);
-     regfree(&CAlist);
-     regfree(&VerifyList);
-diff -Naur Pound-2.6.orig/http.c Pound-2.6.reneg-ciphers-altnames-nosslv2/http.c
---- Pound-2.6.orig/http.c      2011-12-28 14:57:45.000000000 +0100
-+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/http.c    2012-02-15 21:44:46.000000000 +0100
-@@ -246,6 +246,11 @@
- static int  err_to = -1;
-+typedef struct {
-+    int timeout;
-+    RENEG_STATE *reneg_state;
-+} BIO_ARG;
-+
- /*
-  * Time-out for client read/gets
-  * the SSL manual says not to do it, but it works well enough anyway...
-@@ -253,18 +258,32 @@
- static long
- bio_callback(BIO *const bio, const int cmd, const char *argp, int argi, long argl, long ret)
- {
-+    BIO_ARG *bio_arg;
-     struct pollfd   p;
-     int             to, p_res, p_err;
-     if(cmd != BIO_CB_READ && cmd != BIO_CB_WRITE)
-         return ret;
-+    //logmsg(LOG_NOTICE, "bio callback");
-     /* a time-out already occured */
--    if((to = *((int *)BIO_get_callback_arg(bio)) * 1000) < 0) {
-+    if((bio_arg = (BIO_ARG*)BIO_get_callback_arg(bio))==NULL) return ret;
-+    if((to = bio_arg->timeout * 1000) < 0) {
-         errno = ETIMEDOUT;
-         return -1;
-     }
-+    /* Renegotiations */
-+    //logmsg(LOG_NOTICE, "RENEG STATE %d", bio_arg->reneg_state==NULL?-1:*bio_arg->reneg_state);
-+    if (bio_arg->reneg_state != NULL && *bio_arg->reneg_state == RENEG_ABORT) {
-+        logmsg(LOG_NOTICE, "REJECTING renegotiated session");
-+        errno = ECONNABORTED;
-+        return -1;
-+    }
-+
-+    //logmsg(LOG_NOTICE, "TO %d", to);
-+    if (to == 0) return ret;
-+
-     for(;;) {
-         memset(&p, 0, sizeof(p));
-         BIO_get_fd(bio, &p.fd);
-@@ -299,7 +318,7 @@
-             return -1;
-         case 0:
-             /* timeout - mark the BIO as unusable for the future */
--            BIO_set_callback_arg(bio, (char *)&err_to);
-+            bio_arg->timeout = err_to;
- #ifdef  EBUG
-             logmsg(LOG_WARNING, "(%lx) CALLBACK timeout poll after %d secs: %s",
-                 pthread_self(), to / 1000, strerror(p_err));
-@@ -503,7 +522,14 @@
-     regmatch_t          matches[4];
-     struct linger       l;
-     double              start_req, end_req;
-+    RENEG_STATE               reneg_state;
-+    BIO_ARG           ba1, ba2;
-+    reneg_state = RENEG_INIT;
-+    ba1.reneg_state =  &reneg_state;
-+    ba2.reneg_state = &reneg_state;
-+    ba1.timeout = 0;
-+    ba2.timeout = 0;
-     from_host = ((thr_arg *)arg)->from_host;
-     memcpy(&from_host_addr, from_host.ai_addr, from_host.ai_addrlen);
-     from_host.ai_addr = (struct sockaddr *)&from_host_addr;
-@@ -512,6 +538,8 @@
-     free(((thr_arg *)arg)->from_host.ai_addr);
-     free(arg);
-+    if(lstn->allow_client_reneg) reneg_state = RENEG_ALLOW;
-+
-     n = 1;
-     setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&n, sizeof(n));
-     l.l_onoff = 1;
-@@ -535,10 +563,11 @@
-         close(sock);
-         return;
-     }
--    if(lstn->to > 0) {
--        BIO_set_callback_arg(cl, (char *)&lstn->to);
-+    //if(lstn->to > 0) {
-+        ba1.timeout = lstn->to;
-+        BIO_set_callback_arg(cl, (char *)&ba1);
-         BIO_set_callback(cl, bio_callback);
--    }
-+    //}
-     if(lstn->ctx != NULL) {
-         if((ssl = SSL_new(lstn->ctx->ctx)) == NULL) {
-@@ -547,6 +576,7 @@
-             BIO_free_all(cl);
-             return;
-         }
-+        SSL_set_app_data(ssl, &reneg_state);
-         SSL_set_bio(ssl, cl, cl);
-         if((bb = BIO_new(BIO_f_ssl())) == NULL) {
-             logmsg(LOG_WARNING, "(%lx) BIO_new(Bio_f_ssl()) failed", pthread_self());
-@@ -848,7 +878,8 @@
-             }
-             BIO_set_close(be, BIO_CLOSE);
-             if(backend->to > 0) {
--                BIO_set_callback_arg(be, (char *)&backend->to);
-+                ba2.timeout = backend->to;
-+                BIO_set_callback_arg(be, (char *)&ba2);
-                 BIO_set_callback(be, bio_callback);
-             }
-             if(backend->ctx != NULL) {
-diff -Naur Pound-2.6.orig/pound.8 Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.8
---- Pound-2.6.orig/pound.8     2011-12-28 14:57:45.000000000 +0100
-+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.8   2012-02-15 21:44:46.000000000 +0100
-@@ -501,6 +501,19 @@
- and
- .I SSL_CTX_set_cipher_list(3).
- .TP
-+\fBSSLHonorCipherOrder\fR 0|1
-+If this value is 1, the server will broadcast a preference to use \fBCiphers\fR in the
-+order supplied in the \fBCiphers\fR directive.  If the value is 0, the server will treat
-+the Ciphers list as the list of Ciphers it will accept, but no preference will be
-+indicated.  Default value is 0.
-+.TP
-+\fBSSLAllowClientRenegotiation\fR 0|1|2
-+If this value is 0, client initiated renegotiation will be disabled.  This will mitigate
-+DoS exploits based on client renegotiation, regardless of the patch status of clients and
-+servers related to "Secure renegotiation".  If the value is 1, secure renegotiation is
-+supported.  If the value is 2, insecure renegotiation is supported, with unpatched
-+clients.  /fBThis can lead to a DoS and a Man in the Middle attack!/fR  Default value is 0.
-+.TP
- \fBCAlist\fR "CAcert_file"
- Set the list of "trusted" CA's for this server. The CAcert_file is a file containing
- a sequence of CA certificates (PEM format). The names of the defined CA certificates
-diff -Naur Pound-2.6.orig/pound.h Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.h
---- Pound-2.6.orig/pound.h     2011-12-28 14:57:45.000000000 +0100
-+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/pound.h   2012-02-15 21:49:39.000000000 +0100
-@@ -380,6 +380,8 @@
-     SSL_CTX             *ctx;
-     char                *server_name;
-     struct _pound_ctx   *next;
-+    unsigned int        subjectAltNameCount;
-+    unsigned char       **subjectAltNames;
- } POUND_CTX;
- /* Listener definition */
-@@ -404,6 +406,8 @@
-     int                 rewr_dest;      /* rewrite destination header */
-     int                 disabled;       /* true if the listener is disabled */
-     int                 log_level;      /* log level for this listener */
-+    int                 allow_client_reneg; /* Allow Client SSL Renegotiation */
-+    int                disable_ssl_v2; /* Disable SSL version 2 */
-     SERVICE             *services;
-     struct _listener    *next;
- }   LISTENER;
-@@ -419,6 +423,9 @@
-     struct _thr_arg *next;
- }   thr_arg;                        /* argument to processing threads: socket, origin */
-+/* Track SSL handshare/renegotiation so we can reject client-renegotiations. */
-+typedef enum { RENEG_INIT=0, RENEG_REJECT, RENEG_ALLOW, RENEG_ABORT } RENEG_STATE;
-+
- /* Header types */
- #define HEADER_ILLEGAL              -1
- #define HEADER_OTHER                0
-@@ -591,6 +598,11 @@
- extern DH   *DH_tmp_callback(SSL *, int, int);
- /*
-+ * Renegotiation callback
-+ */
-+extern void SSLINFO_callback(const SSL *s, int where, int rc);
-+
-+/*
-  * expiration stuff
-  */
- #ifndef EXPIRE_TO
-diff -Naur Pound-2.6.orig/svc.c Pound-2.6.reneg-ciphers-altnames-nosslv2/svc.c
---- Pound-2.6.orig/svc.c       2011-12-28 14:57:45.000000000 +0100
-+++ Pound-2.6.reneg-ciphers-altnames-nosslv2/svc.c     2012-02-15 21:44:46.000000000 +0100
-@@ -1797,3 +1797,34 @@
-         close(ctl);
-     }
- }
-+
-+void
-+SSLINFO_callback(const SSL *ssl, int where, int rc)
-+{
-+    RENEG_STATE *reneg_state;
-+
-+    /* Get our thr_arg where we're tracking this connection info */
-+    if ((reneg_state = (RENEG_STATE *)SSL_get_app_data(ssl)) == NULL) return;
-+
-+    /* If we're rejecting renegotiations, move to ABORT if Client Hello is being read. */
-+    if ((where & SSL_CB_ACCEPT_LOOP) && *reneg_state == RENEG_REJECT) {
-+        int state = SSL_get_state(ssl);
-+
-+        if (state == SSL3_ST_SR_CLNT_HELLO_A || state == SSL23_ST_SR_CLNT_HELLO_A) {
-+           *reneg_state = RENEG_ABORT;
-+           logmsg(LOG_WARNING,"rejecting client initiated renegotiation");
-+        }
-+    }
-+    else if (where & SSL_CB_HANDSHAKE_DONE && *reneg_state == RENEG_INIT) {
-+       // Reject any followup renegotiations
-+       *reneg_state = RENEG_REJECT;
-+    }
-+
-+    //if (where & SSL_CB_HANDSHAKE_START) logmsg(LOG_DEBUG, "handshake start");
-+    //else if (where & SSL_CB_HANDSHAKE_DONE) logmsg(LOG_DEBUG, "handshake done");
-+    //else if (where & SSL_CB_LOOP) logmsg(LOG_DEBUG, "loop");
-+    //else if (where & SSL_CB_READ) logmsg(LOG_DEBUG, "read");
-+    //else if (where & SSL_CB_WRITE) logmsg(LOG_DEBUG, "write");
-+    //else if (where & SSL_CB_ALERT) logmsg(LOG_DEBUG, "alert");
-+}
-+
diff --git a/src/patches/compat-drivers-3.8-1-u-kref_get_unless_zero.patch b/src/patches/compat-drivers-3.8-1-u-kref_get_unless_zero.patch
deleted file mode 100644 (file)
index 1930d80..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
---- compat-drivers-3.8-1-u/include/linux/compat-3.8.h.orig     2013-05-16 20:35:27.046386772 +0200
-+++ compat-drivers-3.8-1-u/include/linux/compat-3.8.h  2013-05-16 20:35:39.219767618 +0200
-@@ -24,35 +24,6 @@
- /* This backports:
-  *
-- * commit 4b20db3de8dab005b07c74161cb041db8c5ff3a7
-- * Author: Thomas Hellstrom <thellstrom@vmware.com>
-- * Date:   Tue Nov 6 11:31:49 2012 +0000
-- *
-- *    kref: Implement kref_get_unless_zero v3
-- */
--/**
-- * kref_get_unless_zero - Increment refcount for object unless it is zero.
-- * @kref: object.
-- *
-- * Return non-zero if the increment succeeded. Otherwise return 0.
-- *
-- * This function is intended to simplify locking around refcounting for
-- * objects that can be looked up from a lookup structure, and which are
-- * removed from that lookup structure in the object destructor.
-- * Operations on such objects require at least a read lock around
-- * lookup + kref_get, and a write lock around kref_put + remove from lookup
-- * structure. Furthermore, RCU implementations become extremely tricky.
-- * With a lookup followed by a kref_get_unless_zero *with return value check*
-- * locking in the kref_put path can be deferred to the actual removal from
-- * the lookup structure and RCU lookups become trivial.
-- */
--static inline int __must_check kref_get_unless_zero(struct kref *kref)
--{
--      return atomic_add_unless(&kref->refcount, 1, 0);
--}
--
--/* This backports:
-- *
-  * commit 83e68189745ad931c2afd45d8ee3303929233e7f
-  * Author: Matt Fleming <matt.fleming@intel.com>
-  * Date:   Wed Nov 14 09:42:35 2012 +0000
diff --git a/src/patches/compat-wireless-2.6.34-usbnet_compile.patch b/src/patches/compat-wireless-2.6.34-usbnet_compile.patch
deleted file mode 100644 (file)
index 36146fb..0000000
+++ /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 (file)
index eb5d280..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-diff -Naur compat-wireless-2.6.39-1-sn.org/compat/kfifo.c compat-wireless-2.6.39-1-sn/compat/kfifo.c
---- compat-wireless-2.6.39-1-sn.org/compat/kfifo.c     2011-05-24 01:43:48.000000000 +0200
-+++ compat-wireless-2.6.39-1-sn/compat/kfifo.c 2011-05-24 17:20:06.956818313 +0200
-@@ -27,6 +27,10 @@
- #include <linux/uaccess.h>
- #include <linux/kfifo.h>
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Stefani Seibold <stefani@seibold.net>");
-+MODULE_DESCRIPTION("A generic kernel FIFO implementation");
-+
- /*
-  * internal helper to calculate the unused elements in a fifo
-  */
diff --git a/src/patches/compat-wireless-3.5-build_ath5k_only_with_pci.patch b/src/patches/compat-wireless-3.5-build_ath5k_only_with_pci.patch
deleted file mode 100644 (file)
index 2e82157..0000000
+++ /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 (file)
index 633bb67..0000000
+++ /dev/null
@@ -1,5080 +0,0 @@
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/Makefile compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/Makefile
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/Makefile      1970-01-01 01:00:00.000000000 +0100
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/Makefile  2012-07-31 14:23:04.000000000 +0200
-@@ -0,0 +1,6 @@
-+obj-$(CONFIG_LIBERTAS_UAP) += uap8xxx.o
-+
-+uap8xxx-y += uap_main.o uap_sdio_mmc.o
-+uap8xxx-$(CONFIG_PROC_FS) += uap_proc.o uap_debug.o
-+
-+EXTRA_CFLAGS += -DFPNUM='"52"' -DPXA3XX_DMA_ALIGN -DDEBUG_LEVEL1
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_debug.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_debug.c
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_debug.c   1970-01-01 01:00:00.000000000 +0100
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_debug.c       2012-07-31 14:23:04.000000000 +0200
-@@ -0,0 +1,261 @@
-+/** @file uap_debug.c
-+  * @brief This file contains functions for debug proc file.
-+  *
-+  * Copyright (C) 2008-2009, Marvell International Ltd.
-+  *
-+  * This software file (the "File") is distributed by Marvell International
-+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
-+  * (the "License").  You may use, redistribute and/or modify this File in
-+  * accordance with the terms and conditions of the License, a copy of which
-+  * is available along with the File in the gpl.txt file or by writing to
-+  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-+  *
-+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
-+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
-+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
-+  * this warranty disclaimer.
-+  *
-+  */
-+#ifdef CONFIG_PROC_FS
-+#include  "uap_headers.h"
-+
-+/********************************************************
-+              Local Variables
-+********************************************************/
-+
-+#define item_size(n) (sizeof ((uap_adapter *)0)->n)
-+#define item_addr(n) ((u32) &((uap_adapter *)0)->n)
-+
-+#define item_dbg_size(n) (sizeof (((uap_adapter *)0)->dbg.n))
-+#define item_dbg_addr(n) ((u32) &(((uap_adapter *)0)->dbg.n))
-+
-+#define item_dev_size(n) (sizeof ((uap_dev_t *)0)->n)
-+#define item_dev_addr(n) ((u32) &((uap_dev_t *)0)->n)
-+
-+/** MicroAp device offset */
-+#define OFFSET_UAP_DEV                0x01
-+/** Bluetooth adapter offset */
-+#define OFFSET_UAP_ADAPTER    0x02
-+
-+struct debug_data
-+{
-+    /** Name */
-+    char name[32];
-+    /** Size */
-+    u32 size;
-+    /** Address */
-+    u32 addr;
-+    /** Offset */
-+    u32 offset;
-+    /** Flag */
-+    u32 flag;
-+};
-+
-+/* To debug any member of uap_adapter, simply add one line here.
-+ */
-+static struct debug_data items[] = {
-+    {"cmd_sent", item_dev_size(cmd_sent), 0, item_dev_addr(cmd_sent),
-+     OFFSET_UAP_DEV},
-+    {"data_sent", item_dev_size(data_sent), 0, item_dev_addr(data_sent),
-+     OFFSET_UAP_DEV},
-+    {"IntCounter", item_size(IntCounter), 0, item_addr(IntCounter),
-+     OFFSET_UAP_ADAPTER},
-+    {"cmd_pending", item_size(cmd_pending), 0, item_addr(cmd_pending),
-+     OFFSET_UAP_ADAPTER},
-+    {"num_cmd_h2c_fail", item_dbg_size(num_cmd_host_to_card_failure), 0,
-+     item_dbg_addr(num_cmd_host_to_card_failure), OFFSET_UAP_ADAPTER},
-+    {"num_tx_h2c_fail", item_dbg_size(num_tx_host_to_card_failure), 0,
-+     item_dbg_addr(num_tx_host_to_card_failure), OFFSET_UAP_ADAPTER},
-+    {"psmode", item_size(psmode), 0, item_addr(psmode), OFFSET_UAP_ADAPTER},
-+    {"ps_state", item_size(ps_state), 0, item_addr(ps_state),
-+     OFFSET_UAP_ADAPTER},
-+#ifdef DEBUG_LEVEL1
-+    {"drvdbg", sizeof(drvdbg), (u32) & drvdbg, 0, 0}
-+#endif
-+};
-+
-+static int num_of_items = sizeof(items) / sizeof(items[0]);
-+
-+/********************************************************
-+              Global Variables
-+********************************************************/
-+
-+/********************************************************
-+              Local Functions
-+********************************************************/
-+/**
-+ *  @brief proc read function
-+ *
-+ *  @param page          pointer to buffer
-+ *  @param s       read data starting position
-+ *  @param off     offset
-+ *  @param cnt     counter
-+ *  @param eof     end of file flag
-+ *  @param data    data to output
-+ *  @return      number of output data
-+ */
-+static int
-+uap_debug_read(char *page, char **s, off_t off, int cnt, int *eof, void *data)
-+{
-+    int val = 0;
-+    char *p = page;
-+    int i;
-+
-+    struct debug_data *d = (struct debug_data *) data;
-+
-+    if (MODULE_GET == 0)
-+        return UAP_STATUS_FAILURE;
-+
-+    for (i = 0; i < num_of_items; i++) {
-+        if (d[i].size == 1)
-+            val = *((u8 *) d[i].addr);
-+        else if (d[i].size == 2)
-+            val = *((u16 *) d[i].addr);
-+        else if (d[i].size == 4)
-+            val = *((u32 *) d[i].addr);
-+
-+        p += sprintf(p, "%s=%d\n", d[i].name, val);
-+    }
-+    MODULE_PUT;
-+    return p - page;
-+}
-+
-+/**
-+ *  @brief proc write function
-+ *
-+ *  @param f     file pointer
-+ *  @param buf     pointer to data buffer
-+ *  @param cnt     data number to write
-+ *  @param data    data to write
-+ *  @return      number of data
-+ */
-+static int
-+uap_debug_write(struct file *f, const char *buf, unsigned long cnt, void *data)
-+{
-+    int r, i;
-+    char *pdata;
-+    char *p;
-+    char *p0;
-+    char *p1;
-+    char *p2;
-+    struct debug_data *d = (struct debug_data *) data;
-+
-+    if (MODULE_GET == 0)
-+        return UAP_STATUS_FAILURE;
-+
-+    pdata = (char *) kmalloc(cnt, GFP_KERNEL);
-+    if (pdata == NULL) {
-+        MODULE_PUT;
-+        return 0;
-+    }
-+
-+    if (copy_from_user(pdata, buf, cnt)) {
-+        PRINTM(INFO, "Copy from user failed\n");
-+        kfree(pdata);
-+        MODULE_PUT;
-+        return 0;
-+    }
-+
-+    p0 = pdata;
-+    for (i = 0; i < num_of_items; i++) {
-+        do {
-+            p = strstr(p0, d[i].name);
-+            if (p == NULL)
-+                break;
-+            p1 = strchr(p, '\n');
-+            if (p1 == NULL)
-+                break;
-+            p0 = p1++;
-+            p2 = strchr(p, '=');
-+            if (!p2)
-+                break;
-+            p2++;
-+            r = string_to_number(p2);
-+            if (d[i].size == 1)
-+                *((u8 *) d[i].addr) = (u8) r;
-+            else if (d[i].size == 2)
-+                *((u16 *) d[i].addr) = (u16) r;
-+            else if (d[i].size == 4)
-+                *((u32 *) d[i].addr) = (u32) r;
-+            break;
-+        } while (TRUE);
-+    }
-+    kfree(pdata);
-+#ifdef DEBUG_LEVEL1
-+    printk(KERN_ALERT "drvdbg = 0x%x\n", drvdbg);
-+    printk(KERN_ALERT "INFO  (%08lx) %s\n", DBG_INFO,
-+           (drvdbg & DBG_INFO) ? "X" : "");
-+    printk(KERN_ALERT "WARN  (%08lx) %s\n", DBG_WARN,
-+           (drvdbg & DBG_WARN) ? "X" : "");
-+    printk(KERN_ALERT "ENTRY (%08lx) %s\n", DBG_ENTRY,
-+           (drvdbg & DBG_ENTRY) ? "X" : "");
-+    printk(KERN_ALERT "CMD_D (%08lx) %s\n", DBG_CMD_D,
-+           (drvdbg & DBG_CMD_D) ? "X" : "");
-+    printk(KERN_ALERT "DAT_D (%08lx) %s\n", DBG_DAT_D,
-+           (drvdbg & DBG_DAT_D) ? "X" : "");
-+    printk(KERN_ALERT "CMND  (%08lx) %s\n", DBG_CMND,
-+           (drvdbg & DBG_CMND) ? "X" : "");
-+    printk(KERN_ALERT "DATA  (%08lx) %s\n", DBG_DATA,
-+           (drvdbg & DBG_DATA) ? "X" : "");
-+    printk(KERN_ALERT "ERROR (%08lx) %s\n", DBG_ERROR,
-+           (drvdbg & DBG_ERROR) ? "X" : "");
-+    printk(KERN_ALERT "FATAL (%08lx) %s\n", DBG_FATAL,
-+           (drvdbg & DBG_FATAL) ? "X" : "");
-+    printk(KERN_ALERT "MSG   (%08lx) %s\n", DBG_MSG,
-+           (drvdbg & DBG_MSG) ? "X" : "");
-+#endif
-+    MODULE_PUT;
-+    return cnt;
-+}
-+
-+/********************************************************
-+              Global Functions
-+********************************************************/
-+/**
-+ *  @brief create debug proc file
-+ *
-+ *  @param priv          pointer uap_private
-+ *  @param dev     pointer net_device
-+ *  @return      N/A
-+ */
-+void
-+uap_debug_entry(uap_private * priv, struct net_device *dev)
-+{
-+    int i;
-+    struct proc_dir_entry *r;
-+
-+    if (priv->proc_entry == NULL)
-+        return;
-+
-+    for (i = 0; i < num_of_items; i++) {
-+        if (items[i].flag & OFFSET_UAP_ADAPTER)
-+            items[i].addr = items[i].offset + (u32) priv->adapter;
-+        if (items[i].flag & OFFSET_UAP_DEV)
-+            items[i].addr = items[i].offset + (u32) & priv->uap_dev;
-+    }
-+    r = create_proc_entry("debug", 0644, priv->proc_entry);
-+    if (r == NULL)
-+        return;
-+
-+    r->data = &items[0];
-+    r->read_proc = uap_debug_read;
-+    r->write_proc = uap_debug_write;
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
-+    r->owner = THIS_MODULE;
-+#endif
-+}
-+
-+/**
-+ *  @brief remove proc file
-+ *
-+ *  @param priv          pointer uap_private
-+ *  @return      N/A
-+ */
-+void
-+uap_debug_remove(uap_private * priv)
-+{
-+    remove_proc_entry("debug", priv->proc_entry);
-+}
-+
-+#endif
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_drv.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_drv.h
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_drv.h     1970-01-01 01:00:00.000000000 +0100
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_drv.h 2012-07-31 14:23:04.000000000 +0200
-@@ -0,0 +1,667 @@
-+/** @file uap_drv.h
-+  * @brief This file contains Linux OS related definitions and
-+  * declarations, uAP driver
-+  *
-+  * Copyright (C) 2008-2009, Marvell International Ltd.
-+  *
-+  * This software file (the "File") is distributed by Marvell International
-+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
-+  * (the "License").  You may use, redistribute and/or modify this File in
-+  * accordance with the terms and conditions of the License, a copy of which
-+  * is available along with the File in the gpl.txt file or by writing to
-+  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-+  *
-+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
-+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
-+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
-+  * this warranty disclaimer.
-+  *
-+  */
-+
-+#ifndef _UAP_DRV_H
-+#define _UAP_DRV_H
-+
-+/** Driver release version */
-+#define DRIVER_VERSION                "26146"
-+
-+/** True */
-+#ifndef       TRUE
-+#define TRUE                  1
-+#endif
-+/** False */
-+#ifndef       FALSE
-+#define       FALSE                   0
-+#endif
-+
-+/** Bit definitions */
-+#ifndef BIT
-+#define BIT(x)        (1UL << (x))
-+#endif
-+
-+/** Dma addresses are 32-bits wide.  */
-+#ifndef __ATTRIB_ALIGN__
-+#define __ATTRIB_ALIGN__ __attribute__((aligned(4)))
-+#endif
-+
-+/**  attribute pack */
-+#ifndef __ATTRIB_PACK__
-+#define __ATTRIB_PACK__ __attribute__ ((packed))
-+#endif
-+
-+/** Debug Macro definition*/
-+#ifdef        DEBUG_LEVEL1
-+
-+extern u32 drvdbg;
-+
-+/** Debug message control bit definition for drvdbg */
-+/** Debug message */
-+#define       DBG_MSG         BIT(0)
-+/** Debug fatal message */
-+#define DBG_FATAL     BIT(1)
-+/** Debug error message */
-+#define DBG_ERROR     BIT(2)
-+/** Debug data message */
-+#define DBG_DATA      BIT(3)
-+/** Debug command message */
-+#define DBG_CMND      BIT(4)
-+
-+/** Debug data */
-+#define DBG_DAT_D     BIT(16)
-+/** Debug command */
-+#define DBG_CMD_D     BIT(17)
-+
-+/** Debug entry */
-+#define DBG_ENTRY     BIT(28)
-+/** Debug warning */
-+#define DBG_WARN      BIT(29)
-+/** Debug info */
-+#define DBG_INFO      BIT(30)
-+
-+/** Print info */
-+#define       PRINTM_INFO(msg...)  {if (drvdbg & DBG_INFO) printk(KERN_DEBUG msg);}
-+/** Print warn message */
-+#define       PRINTM_WARN(msg...)  {if (drvdbg & DBG_WARN) printk(KERN_DEBUG msg);}
-+/** Print entry */
-+#define       PRINTM_ENTRY(msg...) {if (drvdbg & DBG_ENTRY) printk(KERN_DEBUG msg);}
-+/** Print cmd_d */
-+#define       PRINTM_CMD_D(msg...) {if (drvdbg & DBG_CMD_D) printk(KERN_DEBUG msg);}
-+/** Print data_d */
-+#define       PRINTM_DAT_D(msg...) {if (drvdbg & DBG_DAT_D) printk(KERN_DEBUG msg);}
-+/** Print command */
-+#define       PRINTM_CMND(msg...)  {if (drvdbg & DBG_CMND) printk(KERN_DEBUG msg);}
-+/** Print data */
-+#define       PRINTM_DATA(msg...)  {if (drvdbg & DBG_DATA) printk(KERN_DEBUG msg);}
-+/** Print error message */
-+#define       PRINTM_ERROR(msg...) {if (drvdbg & DBG_ERROR) printk(KERN_DEBUG msg);}
-+/** Print fatal message */
-+#define       PRINTM_FATAL(msg...) {if (drvdbg & DBG_FATAL) printk(KERN_DEBUG msg);}
-+/** Print message */
-+#define       PRINTM_MSG(msg...)   {if (drvdbg & DBG_MSG) printk(KERN_ALERT msg);}
-+/** Print level */
-+#define       PRINTM(level,msg...) PRINTM_##level(msg)
-+
-+#else
-+
-+#define       PRINTM(level,msg...) do {} while (0)
-+
-+#endif /* DEBUG_LEVEL1 */
-+
-+/** Wait until a condition becomes true */
-+#define ASSERT(cond)                                          \
-+do {                                                          \
-+      if (!(cond))                                            \
-+              PRINTM(INFO, "ASSERT: %s, %s:%i\n",             \
-+                     __FUNCTION__, __FILE__, __LINE__);       \
-+} while(0)
-+
-+/** Log enrty point for debugging */
-+#define       ENTER()                 PRINTM(ENTRY, "Enter: %s, %s:%i\n", __FUNCTION__, \
-+                                                      __FILE__, __LINE__)
-+/** Log exit point for debugging */
-+#define       LEAVE()                 PRINTM(ENTRY, "Leave: %s, %s:%i\n", __FUNCTION__, \
-+                                                      __FILE__, __LINE__)
-+
-+#ifdef        DEBUG_LEVEL1
-+/** Dump buffer length */
-+#define DBG_DUMP_BUF_LEN    64
-+/** Maximum dump per line */
-+#define MAX_DUMP_PER_LINE   16
-+/** Data dump length */
-+#define DATA_DUMP_LEN       32
-+
-+static inline void
-+hexdump(char *prompt, u8 * buf, int len)
-+{
-+    int i;
-+    char dbgdumpbuf[DBG_DUMP_BUF_LEN];
-+    char *ptr = dbgdumpbuf;
-+
-+    printk(KERN_DEBUG "%s:\n", prompt);
-+    for (i = 1; i <= len; i++) {
-+        ptr += sprintf(ptr, "%02x ", *buf);
-+        buf++;
-+        if (i % MAX_DUMP_PER_LINE == 0) {
-+            *ptr = 0;
-+            printk(KERN_DEBUG "%s\n", dbgdumpbuf);
-+            ptr = dbgdumpbuf;
-+        }
-+    }
-+    if (len % MAX_DUMP_PER_LINE) {
-+        *ptr = 0;
-+        printk(KERN_DEBUG "%s\n", dbgdumpbuf);
-+    }
-+}
-+
-+/** Debug command */
-+#define DBG_HEXDUMP_CMD_D(x,y,z)    {if (drvdbg & DBG_CMD_D) hexdump(x,y,z);}
-+/** Debug data */
-+#define DBG_HEXDUMP_DAT_D(x,y,z)    {if (drvdbg & DBG_DAT_D) hexdump(x,y,z);}
-+/** Debug hexdump */
-+#define       DBG_HEXDUMP(level,x,y,z)    DBG_HEXDUMP_##level(x,y,z)
-+/** hexdump */
-+#define HEXDUMP(x,y,z)              {if (drvdbg & DBG_INFO) hexdump(x,y,z);}
-+#else
-+/** Do nothing since debugging is not turned on */
-+#define DBG_HEXDUMP(level,x,y,z)    do {} while (0)
-+/** Do nothing since debugging is not turned on */
-+#define HEXDUMP(x,y,z)              do {} while (0)
-+#endif
-+
-+/**
-+ * Typedefs
-+ */
-+/** Unsigned char */
-+typedef u8 BOOLEAN;
-+
-+/*
-+ * OS macro definitions
-+ */
-+/** OS macro to get time */
-+#define os_time_get() jiffies
-+
-+/** OS macro to update transfer start time */
-+#define UpdateTransStart(dev) { \
-+      dev->trans_start = jiffies; \
-+}
-+
-+/** Try to get a reference to the module */
-+#define MODULE_GET    try_module_get(THIS_MODULE)
-+/** Decrease module reference count */
-+#define MODULE_PUT    module_put(THIS_MODULE)
-+
-+/** OS macro to initialize semaphore */
-+#define OS_INIT_SEMAPHORE(x)  sema_init(x,1)
-+/** OS macro to acquire blocking semaphore */
-+#define OS_ACQ_SEMAPHORE_BLOCK(x)     down_interruptible(x)
-+/** OS macro to acquire non-blocking semaphore */
-+#define OS_ACQ_SEMAPHORE_NOBLOCK(x)   down_trylock(x)
-+/** OS macro to release semaphore */
-+#define OS_REL_SEMAPHORE(x)           up(x)
-+
-+static inline void
-+os_sched_timeout(u32 millisec)
-+{
-+    set_current_state(TASK_INTERRUPTIBLE);
-+    schedule_timeout((millisec * HZ) / 1000);
-+}
-+
-+/** Maximum size of ethernet packet */
-+#define MRVDRV_MAXIMUM_ETH_PACKET_SIZE        1514
-+
-+/** Maximum size of multicast list */
-+#define MRVDRV_MAX_MULTICAST_LIST_SIZE        32
-+
-+/** Find minimum */
-+#ifndef MIN
-+#define MIN(a,b)              ((a) < (b) ? (a) : (b))
-+#endif
-+
-+/** Find maximum */
-+#ifndef MAX
-+#define MAX(a,b)              ((a) > (b) ? (a) : (b))
-+#endif
-+
-+/** Find number of elements */
-+#ifndef NELEMENTS
-+#define NELEMENTS(x) (sizeof(x)/sizeof(x[0]))
-+#endif
-+
-+/** Buffer Constants */
-+
-+/** Size of command buffer */
-+#define MRVDRV_SIZE_OF_CMD_BUFFER       (2 * 1024)
-+
-+/** Length of device length */
-+#define DEV_NAME_LEN                  32
-+
-+/** Length of ethernet address */
-+#ifndef       ETH_ALEN
-+#define ETH_ALEN                      6
-+#endif
-+
-+/** Default watchdog timeout */
-+#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (2 * HZ)
-+
-+/** Success */
-+#define UAP_STATUS_SUCCESS         (0)
-+/** Failure */
-+#define UAP_STATUS_FAILURE         (-1)
-+/** Not accepted */
-+#define UAP_STATUS_NOT_ACCEPTED    (-2)
-+
-+/** Max loop count (* 100ms) for waiting device ready at init time */
-+#define MAX_WAIT_DEVICE_READY_COUNT   50
-+
-+/** Tx high watermark. Stop Tx queue after this is crossed */
-+#define TX_HIGH_WATERMARK   4
-+/** Tx low watermark. Restart Tx queue after this is crossed */
-+#define TX_LOW_WATERMARK    2
-+
-+/** Netlink protocol number */
-+#define NETLINK_MARVELL     (MAX_LINKS - 1)
-+/** Netlink maximum payload size */
-+#define NL_MAX_PAYLOAD      1024
-+/** Netlink multicast group number */
-+#define NL_MULTICAST_GROUP  1
-+
-+/** 20 seconds */
-+#define MRVDRV_TIMER_20S              20000
-+
-+/** Host Command option for wait till Send */
-+#define HostCmd_OPTION_WAITFORSEND            0x0001
-+/** Host Command option for wait for RSP */
-+#define HostCmd_OPTION_WAITFORRSP             0x0002
-+/** Host Command option for wait for RSP or Timeout */
-+#define HostCmd_OPTION_WAITFORRSP_TIMEOUT     0x0003
-+/** Host Command option for wait for RSP of sleep confirm */
-+#define HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM   0x0004
-+
-+/** Sleep until a condition gets true or a timeout elapses */
-+#define os_wait_interruptible_timeout(waitq, cond, timeout) \
-+      wait_event_interruptible_timeout(waitq, cond, ((timeout) * HZ / 1000))
-+
-+/** Private command ID to Host command */
-+#define       UAPHOSTCMD                      (SIOCDEVPRIVATE + 1)
-+
-+/** Private command ID to Power Mode */
-+#define       UAP_POWER_MODE                  (SIOCDEVPRIVATE + 3)
-+/** sleep_param */
-+typedef struct _ps_sleep_param
-+{
-+    /** control bitmap */
-+    u32 ctrl_bitmap;
-+    /** minimum sleep period (micro second) */
-+    u32 min_sleep;
-+    /** maximum sleep period (micro second) */
-+    u32 max_sleep;
-+} ps_sleep_param;
-+
-+/** inactivity sleep_param */
-+typedef struct _inact_sleep_param
-+{
-+    /** inactivity timeout (micro second) */
-+    u32 inactivity_to;
-+    /** miniumu awake period (micro second) */
-+    u32 min_awake;
-+    /** maximum awake period (micro second) */
-+    u32 max_awake;
-+} inact_sleep_param;
-+
-+/** flag for ps mode */
-+#define PS_FLAG_PS_MODE                 1
-+/** flag for sleep param */
-+#define PS_FLAG_SLEEP_PARAM             2
-+/** flag for inactivity sleep param */
-+#define PS_FLAG_INACT_SLEEP_PARAM       4
-+
-+/** Disable power mode */
-+#define PS_MODE_DISABLE                      0
-+/** Enable periodic dtim ps */
-+#define PS_MODE_PERIODIC_DTIM                1
-+/** Enable inactivity ps */
-+#define PS_MODE_INACTIVITY                   2
-+
-+/** sleep parameter */
-+#define SLEEP_PARAMETER                     1
-+/** inactivity sleep parameter */
-+#define INACTIVITY_SLEEP_PARAMETER          2
-+/** ps_mgmt */
-+typedef struct _ps_mgmt
-+{
-+    /** flags for valid field */
-+    u16 flags;
-+    /** power mode */
-+    u16 ps_mode;
-+    /** sleep param */
-+    ps_sleep_param sleep_param;
-+    /** inactivity sleep param */
-+    inact_sleep_param inact_param;
-+} ps_mgmt;
-+
-+/** Semaphore structure */
-+typedef struct semaphore SEMAPHORE;
-+
-+/** Global Varibale Declaration */
-+/** Private data structure of the device */
-+typedef struct _uap_private uap_private;
-+/** Adapter data structure of the device */
-+typedef struct _uap_adapter uap_adapter;
-+/** private structure */
-+extern uap_private *uappriv;
-+
-+/** ENUM definition*/
-+
-+/** Hardware status codes */
-+typedef enum _HARDWARE_STATUS
-+{
-+    HWReady,
-+    HWInitializing,
-+    HWReset,
-+    HWClosing,
-+    HWNotReady
-+} HARDWARE_STATUS;
-+
-+/** info for debug purpose */
-+typedef struct _uap_dbg
-+{
-+        /** Number of host to card command failures */
-+    u32 num_cmd_host_to_card_failure;
-+        /** Number of host to card Tx failures */
-+    u32 num_tx_host_to_card_failure;
-+} uap_dbg;
-+
-+/** Set thread state */
-+#define OS_SET_THREAD_STATE(x)                set_current_state(x)
-+
-+typedef struct
-+{
-+    /** Task */
-+    struct task_struct *task;
-+    /** Queue */
-+    wait_queue_head_t waitQ;
-+    /** PID */
-+    pid_t pid;
-+    /** Private structure */
-+    void *priv;
-+} uap_thread;
-+
-+static inline void
-+uap_activate_thread(uap_thread * thr)
-+{
-+        /** Record the thread pid */
-+    thr->pid = current->pid;
-+
-+        /** Initialize the wait queue */
-+    init_waitqueue_head(&thr->waitQ);
-+}
-+
-+static inline void
-+uap_deactivate_thread(uap_thread * thr)
-+{
-+    thr->pid = 0;
-+    return;
-+}
-+
-+static inline void
-+uap_create_thread(int (*uapfunc) (void *), uap_thread * thr, char *name)
-+{
-+    thr->task = kthread_run(uapfunc, thr, "%s", name);
-+}
-+
-+static inline int
-+uap_terminate_thread(uap_thread * thr)
-+{
-+    /* Check if the thread is active or not */
-+    if (!thr->pid)
-+        return -1;
-+    kthread_stop(thr->task);
-+    return 0;
-+}
-+
-+/** Data structure for the Marvell uAP device */
-+typedef struct _uap_dev
-+{
-+        /** device name */
-+    char name[DEV_NAME_LEN];
-+        /** card pointer */
-+    void *card;
-+        /** IO port */
-+    u32 ioport;
-+        /** Rx unit */
-+    u8 rx_unit;
-+        /** Data sent:
-+          TRUE - Data is sent to fw, no Tx Done received
-+          FALSE - Tx done received for previous Tx */
-+    BOOLEAN data_sent;
-+        /** CMD sent:
-+          TRUE - CMD is sent to fw, no CMD Done received
-+          FALSE - CMD done received for previous CMD */
-+    BOOLEAN cmd_sent;
-+        /** netdev pointer */
-+    struct net_device *netdev;
-+} uap_dev_t, *puap_dev_t;
-+
-+/** Private structure for the MV device */
-+struct _uap_private
-+{
-+        /** Device open */
-+    int open;
-+
-+        /** Device adapter structure */
-+    uap_adapter *adapter;
-+        /** Device structure */
-+    uap_dev_t uap_dev;
-+
-+        /** Net device statistics structure */
-+    struct net_device_stats stats;
-+
-+        /** Number of Tx timeouts */
-+    u32 num_tx_timeout;
-+
-+        /** Media connection status */
-+    BOOLEAN MediaConnected;
-+
-+#ifdef CONFIG_PROC_FS
-+    struct proc_dir_entry *proc_uap;
-+    struct proc_dir_entry *proc_entry;
-+#endif                          /* CONFIG_PROC_FS */
-+
-+        /** Firmware helper */
-+    const struct firmware *fw_helper;
-+        /** Firmware */
-+    const struct firmware *firmware;
-+        /** Hotplug device */
-+    struct device *hotplug_device;
-+        /** thread to service interrupts */
-+    uap_thread MainThread;
-+        /** Driver lock */
-+    spinlock_t driver_lock;
-+        /** Driver lock flags */
-+    ulong driver_flags;
-+
-+};
-+
-+/** PS_CMD_ConfirmSleep */
-+typedef struct _PS_CMD_ConfirmSleep
-+{
-+        /** SDIO Length */
-+    u16 SDLen;
-+    /** SDIO Type */
-+    u16 SDType;
-+        /** Command */
-+    u16 Command;
-+        /** Size */
-+    u16 Size;
-+        /** Sequence number */
-+    u16 SeqNum;
-+        /** Result */
-+    u16 Result;
-+} __ATTRIB_PACK__ PS_CMD_ConfirmSleep, *PPS_CMD_ConfirmSleep;
-+
-+/** Wlan Adapter data structure*/
-+struct _uap_adapter
-+{
-+        /** Power save confirm sleep command */
-+    PS_CMD_ConfirmSleep PSConfirmSleep;
-+        /** Device status */
-+    HARDWARE_STATUS HardwareStatus;
-+        /** Interrupt counter */
-+    u32 IntCounter;
-+        /** Tx packet queue */
-+    struct sk_buff_head tx_queue;
-+        /** Cmd packet queue */
-+    struct sk_buff_head cmd_queue;
-+        /** Command sequence number */
-+    u16 SeqNum;
-+        /** Command buffer */
-+    u8 *CmdBuf;
-+        /** cmd pending flag */
-+    u8 cmd_pending;
-+        /** cmd wait option */
-+    u8 cmd_wait_option;
-+        /** Command buffer length */
-+    u32 CmdSize;
-+        /** Command wait queue */
-+    wait_queue_head_t cmdwait_q __ATTRIB_ALIGN__;
-+        /** Command wait queue state flag */
-+    u8 CmdWaitQWoken;
-+        /** PnP support */
-+    BOOLEAN SurpriseRemoved;
-+        /** Debug */
-+    uap_dbg dbg;
-+        /** Netlink kernel socket */
-+    struct sock *nl_sk;
-+        /** Semaphore for CMD */
-+    SEMAPHORE CmdSem;
-+         /** Power Save mode */
-+    u8 psmode;
-+        /** Power Save state */
-+    u8 ps_state;
-+        /** Number of wakeup tries */
-+    u32 WakeupTries;
-+};
-+
-+static inline int
-+os_upload_rx_packet(uap_private * priv, struct sk_buff *skb)
-+{
-+    skb->dev = priv->uap_dev.netdev;
-+    skb->protocol = eth_type_trans(skb, priv->uap_dev.netdev);
-+    skb->ip_summed = CHECKSUM_UNNECESSARY;
-+    if (in_interrupt())
-+        netif_rx(skb);
-+    else
-+        netif_rx_ni(skb);
-+    return 0;
-+}
-+
-+/*
-+ *  netif carrier_on/off and start(wake)/stop_queue handling
-+ */
-+static inline void
-+os_carrier_on(uap_private * priv)
-+{
-+    if (!netif_carrier_ok(priv->uap_dev.netdev) &&
-+        (priv->MediaConnected == TRUE)) {
-+        netif_carrier_on(priv->uap_dev.netdev);
-+    }
-+}
-+
-+static inline void
-+os_carrier_off(uap_private * priv)
-+{
-+    if (netif_carrier_ok(priv->uap_dev.netdev)) {
-+        netif_carrier_off(priv->uap_dev.netdev);
-+    }
-+}
-+
-+static inline void
-+os_start_queue(uap_private * priv)
-+{
-+    if (netif_queue_stopped(priv->uap_dev.netdev) &&
-+        (priv->MediaConnected == TRUE)) {
-+        netif_wake_queue(priv->uap_dev.netdev);
-+    }
-+}
-+
-+static inline void
-+os_stop_queue(uap_private * priv)
-+{
-+    if (!netif_queue_stopped(priv->uap_dev.netdev)) {
-+        netif_stop_queue(priv->uap_dev.netdev);
-+    }
-+}
-+
-+/** Interface specific header */
-+#define INTF_HEADER_LEN         4
-+
-+/** headroom alignment for tx packet */
-+#define HEADER_ALIGNMENT      8
-+
-+/** The number of times to try when polling for status bits */
-+#define MAX_POLL_TRIES                        100
-+
-+/** Length of SNAP header */
-+#define MRVDRV_SNAP_HEADER_LEN          8
-+
-+/** Extra length of Tx packet buffer */
-+#define EXTRA_LEN     36
-+
-+/** Buffer size for ethernet Tx packets */
-+#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \
-+      (ETH_FRAME_LEN + sizeof(TxPD) + EXTRA_LEN)
-+
-+/** Buffer size for ethernet Rx packets */
-+#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \
-+      (ETH_FRAME_LEN + sizeof(RxPD) \
-+       + MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN)
-+
-+/** Packet type: data, command & event */
-+typedef enum _mv_type
-+{
-+    MV_TYPE_DAT = 0,
-+    MV_TYPE_CMD = 1,
-+    MV_TYPE_EVENT = 3
-+} mv_type;
-+
-+/** Disable interrupt */
-+#define OS_INT_DISABLE        spin_lock_irqsave(&priv->driver_lock, priv->driver_flags)
-+/** Enable interrupt */
-+#define       OS_INT_RESTORE  spin_unlock_irqrestore(&priv->driver_lock, priv->driver_flags)
-+
-+int uap_process_rx_packet(uap_private * priv, struct sk_buff *skb);
-+void uap_interrupt(uap_private * priv);
-+uap_private *uap_add_card(void *card);
-+int uap_remove_card(void *card);
-+int uap_process_event(uap_private * priv, u8 * payload, uint len);
-+int uap_soft_reset(uap_private * priv);
-+int uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len);
-+
-+#ifdef CONFIG_PROC_FS
-+/** The proc fs interface */
-+void uap_proc_entry(uap_private * priv, struct net_device *dev);
-+void uap_proc_remove(uap_private * priv);
-+int string_to_number(char *s);
-+void uap_debug_entry(uap_private * priv, struct net_device *dev);
-+void uap_debug_remove(uap_private * priv);
-+#endif /* CONFIG_PROC_FS */
-+
-+int sbi_register(void);
-+
-+void sbi_unregister(void);
-+int sbi_register_dev(uap_private * priv);
-+int sbi_unregister_dev(uap_private * priv);
-+int sbi_prog_fw_w_helper(uap_private *);
-+
-+int sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb);
-+int sbi_enable_host_int(uap_private * priv);
-+int sbi_disable_host_int(uap_private * priv);
-+
-+int sbi_get_int_status(uap_private * priv, u8 * ireg);
-+/** Check firmware status */
-+int sbi_check_fw_status(uap_private *, int);
-+int sbi_prog_helper(uap_private *);
-+
-+int sbi_wakeup_firmware(uap_private * priv);
-+
-+#endif /* _UAP_DRV_H */
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_fw.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_fw.h
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_fw.h      1970-01-01 01:00:00.000000000 +0100
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_fw.h  2012-07-31 14:23:04.000000000 +0200
-@@ -0,0 +1,359 @@
-+/** @file uap_fw.h
-+ *
-+ * @brief This file contains firmware specific defines.
-+ *
-+ * Copyright (C) 2008-2009, Marvell International Ltd.
-+ *
-+ * This software file (the "File") is distributed by Marvell International
-+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
-+ * (the "License").  You may use, redistribute and/or modify this File in
-+ * accordance with the terms and conditions of the License, a copy of which
-+ * is available along with the File in the gpl.txt file or by writing to
-+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-+ *
-+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
-+ * this warranty disclaimer.
-+ *
-+ */
-+/********************************************************
-+Change log:
-+      02/26/08: Initial creation
-+********************************************************/
-+
-+#ifndef _UAP_FW_H
-+#define _UAP_FW_H
-+
-+/** uap upload size */
-+#define       UAP_UPLD_SIZE                   2312
-+/** Packet type Micro AP */
-+#define PKT_TYPE_MICROAP              1
-+/** Packet type client */
-+#define PKT_TYPE_CLIENT                       0
-+
-+/** TxPD descriptor */
-+typedef struct _TxPD
-+{
-+        /** Bss Type */
-+    u8 BssType;
-+        /** Bss num */
-+    u8 BssNum;
-+        /** Tx packet length */
-+    u16 TxPktLength;
-+        /** Tx packet offset */
-+    u16 TxPktOffset;
-+        /** Tx packet type */
-+    u16 TxPktType;
-+        /** Tx Control */
-+    u32 TxControl;
-+        /** reserved */
-+    u32 reserved[2];
-+} __ATTRIB_PACK__ TxPD, *PTxPD;
-+
-+/** RxPD Descriptor */
-+typedef struct _RxPD
-+{
-+        /** Bss Type */
-+    u8 BssType;
-+        /** Bss Num */
-+    u8 BssNum;
-+        /** Tx packet length */
-+    u16 RxPktLength;
-+        /** Tx packet offset */
-+    u16 RxPktOffset;
-+} __ATTRIB_PACK__ RxPD, *PRxPD;
-+
-+#ifdef BIG_ENDIAN
-+/** Convert from 16 bit little endian format to CPU format */
-+#define uap_le16_to_cpu(x) le16_to_cpu(x)
-+/** Convert from 32 bit little endian format to CPU format */
-+#define uap_le32_to_cpu(x) le32_to_cpu(x)
-+/** Convert from 64 bit little endian format to CPU format */
-+#define uap_le64_to_cpu(x) le64_to_cpu(x)
-+/** Convert to 16 bit little endian format from CPU format */
-+#define uap_cpu_to_le16(x) cpu_to_le16(x)
-+/** Convert to 32 bit little endian format from CPU format */
-+#define uap_cpu_to_le32(x) cpu_to_le32(x)
-+/** Convert to 64 bit little endian format from CPU format */
-+#define uap_cpu_to_le64(x) cpu_to_le64(x)
-+
-+/** Convert TxPD to little endian format from CPU format */
-+#define endian_convert_TxPD(x);                                         \
-+    {                                                                   \
-+        (x)->TxPktLength = uap_cpu_to_le16((x)->TxPktLength);         \
-+        (x)->TxPktOffset = uap_cpu_to_le32((x)->TxPktOffset);         \
-+        (x)->TxControl = uap_cpu_to_le32((x)->TxControl);              \
-+        (x)->TxPktType = uap_cpu_to_le32((x)->TxPktType);             \
-+    }
-+
-+/** Convert RxPD from little endian format to CPU format */
-+#define endian_convert_RxPD(x);                                       \
-+    {                                                                 \
-+        (x)->RxPktLength = uap_le16_to_cpu((x)->RxPktLength);         \
-+        (x)->RxPktOffset = uap_le32_to_cpu((x)->RxPktOffset);         \
-+    }
-+#else /* BIG_ENDIAN */
-+/** Do nothing */
-+#define uap_le16_to_cpu(x) x
-+/** Do nothing */
-+#define uap_le32_to_cpu(x) x
-+/** Do nothing */
-+#define uap_le64_to_cpu(x) x
-+/** Do nothing */
-+#define uap_cpu_to_le16(x) x
-+/** Do nothing */
-+#define uap_cpu_to_le32(x) x
-+/** Do nothing */
-+#define uap_cpu_to_le64(x) x
-+
-+/** Do nothing */
-+#define endian_convert_TxPD(x)
-+/** Do nothing */
-+#define endian_convert_RxPD(x)
-+#endif /* BIG_ENDIAN */
-+
-+/** Host Command ID : Function initialization */
-+#define HostCmd_CMD_FUNC_INIT                 0x00a9
-+/** Host Command ID : Function shutdown */
-+#define HostCmd_CMD_FUNC_SHUTDOWN             0x00aa
-+
-+/** Host Command id: SYS_INFO  */
-+#define HOST_CMD_APCMD_SYS_INFO               0x00ae
-+/** Host Command id: SYS_RESET  */
-+#define HOST_CMD_APCMD_SYS_RESET              0x00af
-+/** Host Command id: SYS_CONFIGURE  */
-+#define HOST_CMD_APCMD_SYS_CONFIGURE          0x00b0
-+/** Host Command id: BSS_START  */
-+#define HOST_CMD_APCMD_BSS_START              0x00b1
-+/** Host Command id: SYS_STOP  */
-+#define HOST_CMD_APCMD_BSS_STOP               0x00b2
-+/** Host Command id: STA_LIST  */
-+#define HOST_CMD_APCMD_STA_LIST               0x00b3
-+/** Host Command id: STA_FILTER_TABLE  */
-+#define HOST_CMD_APCMD_STA_FILTER_TABLE       0x00b4
-+/** Host Command id: STA_DEAUTH  */
-+#define HOST_CMD_APCMD_STA_DEAUTH             0x00b5
-+/** Host Command id: SOFT_RESET  */
-+#define HOST_CMD_APCMD_SOFT_RESET             0x00d5
-+/** Host Command id: POWER_MGMT_EXT  */
-+#define HOST_CMD_POWER_MGMT_EXT               0x00ef
-+/** Host Command id: SLEEP_CONFIRM*/
-+#define HOST_CMD_SLEEP_CONFIRM              0x00d8
-+
-+/** TLV type : SSID */
-+#define TLV_TYPE_SSID                         0x0000
-+/** TLV type : Rates */
-+#define TLV_TYPE_RATES                                0x0001
-+/** TLV type : PHY DS */
-+#define TLV_TYPE_PHY_DS                               0x0003
-+
-+/** TLV Id : Base id */
-+#define PROPRIETARY_TLV_BASE_ID               0x0100
-+/** TLV Id : AP_MAC_ADDRESS */
-+#define MRVL_AP_MAC_ADDRESS_TLV_ID      (PROPRIETARY_TLV_BASE_ID + 43)
-+/** TLV Id : Beacon period */
-+#define MRVL_BEACON_PERIOD_TLV_ID       (PROPRIETARY_TLV_BASE_ID + 44)
-+/** TLV Id : Dtim period */
-+#define MRVL_DTIM_PERIOD_TLV_ID         (PROPRIETARY_TLV_BASE_ID + 45)
-+/** TLV Id : Basic rates */
-+#define MRVL_BASIC_RATES_TLV_ID         (PROPRIETARY_TLV_BASE_ID + 46)
-+/** TLV Id : Tx Power */
-+#define MRVL_TX_POWER_TLV_ID            (PROPRIETARY_TLV_BASE_ID + 47)
-+/** TLV Id : Broadcast SSID control */
-+#define MRVL_BCAST_SSID_CTL_TLV_ID      (PROPRIETARY_TLV_BASE_ID + 48)
-+/** TLV Id : Preamble control */
-+#define MRVL_PREAMBLE_CTL_TLV_ID        (PROPRIETARY_TLV_BASE_ID + 49)
-+/** TLV Id : Antenna control */
-+#define MRVL_ANTENNA_CTL_TLV_ID         (PROPRIETARY_TLV_BASE_ID + 50)
-+/** TLV Id : RTS threshold */
-+#define MRVL_RTS_THRESHOLD_TLV_ID       (PROPRIETARY_TLV_BASE_ID + 51)
-+/** TLV Id : Radio control */
-+#define MRVL_RADIO_CTL_TLV_ID           (PROPRIETARY_TLV_BASE_ID + 52)
-+/** TLV Id : TX data rate */
-+#define MRVL_TX_DATA_RATE_TLV_ID        (PROPRIETARY_TLV_BASE_ID + 53)
-+/** TLV Id : Packet forward control */
-+#define MRVL_PKT_FWD_CTL_TLV_ID         (PROPRIETARY_TLV_BASE_ID + 54)
-+/** TLV Id : STA info */
-+#define MRVL_STA_INFO_TLV_ID            (PROPRIETARY_TLV_BASE_ID + 55)
-+/** TLV Id : STA MAC address filter */
-+#define MRVL_STA_MAC_ADDR_FILTER_TLV_ID (PROPRIETARY_TLV_BASE_ID + 56)
-+/** TLV Id : STA ageout timer */
-+#define MRVL_STA_AGEOUT_TIMER_TLV_ID    (PROPRIETARY_TLV_BASE_ID + 57)
-+/** TLV Id : Security config */
-+#define MRVL_SECURITY_CFG_TLV_ID        (PROPRIETARY_TLV_BASE_ID + 58)
-+/** TLV Id : WEP KEY */
-+#define MRVL_WEP_KEY_TLV_ID             (PROPRIETARY_TLV_BASE_ID + 59)
-+/** TLV Id : WPA Passphrase */
-+#define MRVL_WPA_PASSPHRASE_TLV_ID      (PROPRIETARY_TLV_BASE_ID + 60)
-+
-+/** Action get */
-+#define ACTION_GET    0
-+/** Action set */
-+#define ACTION_SET    1
-+/** Length of ethernet address */
-+#ifndef       ETH_ALEN
-+#define ETH_ALEN                      6
-+#endif
-+
-+/** HostCmd_DS_GEN */
-+typedef struct
-+{
-+    /** Command */
-+    u16 Command;
-+    /** Size */
-+    u16 Size;
-+    /** Sequence number */
-+    u16 SeqNum;
-+    /** Result */
-+    u16 Result;
-+} __ATTRIB_PACK__ HostCmd_DS_GEN;
-+
-+/** Size of HostCmd_DS_GEN */
-+#define S_DS_GEN    sizeof(HostCmd_DS_GEN)
-+
-+/** _HostCmd_HEADER*/
-+typedef struct
-+{
-+    /** Command Header : Command */
-+    u16 Command;
-+    /** Command Header : Size */
-+    u16 Size;
-+} __ATTRIB_PACK__ HostCmd_HEADER;
-+
-+/** HostCmd_SYS_CONFIG */
-+typedef struct _HostCmd_SYS_CONFIG
-+{
-+        /** CMD Action GET/SET*/
-+    u16 Action;
-+        /** Tlv buffer */
-+    u8 TlvBuffer[0];
-+} __ATTRIB_PACK__ HostCmd_SYS_CONFIG;
-+
-+/** HostCmd_DS_POWER_MGMT_EXT */
-+typedef struct _HostCmd_DS_POWER_MGMT_EXT
-+{
-+    /** CMD Action Get/Set*/
-+    u16 action;
-+    /** power mode */
-+    u16 power_mode;
-+} __ATTRIB_PACK__ HostCmd_DS_POWER_MGMT_EXT;
-+
-+/** _HostCmd_DS_COMMAND*/
-+typedef struct _HostCmd_DS_COMMAND
-+{
-+
-+        /** Command Header : Command */
-+    u16 Command;
-+        /** Command Header : Size */
-+    u16 Size;
-+        /** Command Header : Sequence number */
-+    u16 SeqNum;
-+        /** Command Header : Result */
-+    u16 Result;
-+        /** Command Body */
-+    union
-+    {
-+        HostCmd_SYS_CONFIG sys_config;
-+        HostCmd_DS_POWER_MGMT_EXT pm_cfg;
-+
-+    } params;
-+} __ATTRIB_PACK__ HostCmd_DS_COMMAND;
-+
-+/** MrvlIEtypesHeader_*/
-+typedef struct _MrvlIEtypesHeader
-+{
-+    /** Header type */
-+    u16 Type;
-+    /** Header length */
-+    u16 Len;
-+} __ATTRIB_PACK__ MrvlIEtypesHeader_t;
-+
-+/** MrvlIEtypes_Data_t */
-+typedef struct _MrvlIEtypes_Data_t
-+{
-+    /** Header */
-+    MrvlIEtypesHeader_t Header;
-+    /** Data */
-+    u8 Data[1];
-+} __ATTRIB_PACK__ MrvlIEtypes_Data_t;
-+
-+/** MrvlIEtypes_ChanListParamSet_t */
-+typedef struct _MrvlIEtypes_MacAddr_t
-+{
-+    /** Header */
-+    MrvlIEtypesHeader_t Header;
-+    /** AP MAC address */
-+    u8 ApMacAddr[ETH_ALEN];
-+} __ATTRIB_PACK__ MrvlIEtypes_MacAddr_t;
-+
-+/** Event ID: BSS started */
-+#define MICRO_AP_EV_ID_BSS_START    46
-+
-+/** Event ID: BSS idle event */
-+#define MICRO_AP_EV_BSS_IDLE       67
-+
-+/** Event ID: BSS active event */
-+#define MICRO_AP_EV_BSS_ACTIVE             68
-+
-+/** Event ID: PS_AWAKE */
-+#define EVENT_PS_AWAKE     0x0a
-+
-+/** Event ID: PS_SLEEP */
-+#define EVENT_PS_SLEEP     0x0b
-+
-+/** PS_STATE */
-+typedef enum _PS_STATE
-+{
-+    PS_STATE_AWAKE,
-+    PS_STATE_PRE_SLEEP,
-+    PS_STATE_SLEEP
-+} PS_STATE;
-+
-+/** TLV type: AP Sleep param */
-+#define TLV_TYPE_AP_SLEEP_PARAM         (PROPRIETARY_TLV_BASE_ID + 106)
-+/** TLV type: AP Inactivity Sleep param */
-+#define TLV_TYPE_AP_INACT_SLEEP_PARAM   (PROPRIETARY_TLV_BASE_ID + 107)
-+
-+/** MrvlIEtypes_sleep_param_t */
-+typedef struct _MrvlIEtypes_sleep_param_t
-+{
-+    /** Header */
-+    MrvlIEtypesHeader_t header;
-+    /** control bitmap */
-+    u32 ctrl_bitmap;
-+    /** min_sleep */
-+    u32 min_sleep;
-+    /** max_sleep */
-+    u32 max_sleep;
-+} __ATTRIB_PACK__ MrvlIEtypes_sleep_param_t;
-+
-+/** MrvlIEtypes_inact_sleep_param_t */
-+typedef struct _MrvlIEtypes_inact_sleep_param_t
-+{
-+    /** Header */
-+    MrvlIEtypesHeader_t header;
-+    /** inactivity timeout */
-+    u32 inactivity_to;
-+    /** min_awake */
-+    u32 min_awake;
-+    /** max_awake */
-+    u32 max_awake;
-+} __ATTRIB_PACK__ MrvlIEtypes_inact_sleep_param_t;
-+
-+/** AP_Event */
-+typedef struct _AP_Event
-+{
-+    /** Event ID */
-+    u32 EventId;
-+    /*
-+     * Reserved for STA_ASSOCIATED event and contains
-+     * status information for the MIC_COUNTERMEASURES event.
-+     */
-+    /** Reserved/status */
-+    u16 status;
-+    /** AP MAC address */
-+    u8 MacAddr[ETH_ALEN];
-+} __ATTRIB_PACK__ AP_Event;
-+#endif /* _UAP_FW_H */
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_headers.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_headers.h
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_headers.h 1970-01-01 01:00:00.000000000 +0100
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_headers.h     2012-07-31 14:23:04.000000000 +0200
-@@ -0,0 +1,64 @@
-+/** @file uap_headers.h
-+ *
-+ * @brief This file contains all the necessary include file.
-+ *
-+  * Copyright (C) 2008-2009, Marvell International Ltd.
-+ *
-+ * This software file (the "File") is distributed by Marvell International
-+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
-+ * (the "License").  You may use, redistribute and/or modify this File in
-+ * accordance with the terms and conditions of the License, a copy of which
-+ * is available along with the File in the gpl.txt file or by writing to
-+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-+ *
-+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
-+ * this warranty disclaimer.
-+ *
-+ */
-+#ifndef _UAP_HEADERS_H
-+#define _UAP_HEADERS_H
-+
-+/* Linux header files */
-+#include    <linux/kernel.h>
-+#include    <linux/module.h>
-+#include    <linux/init.h>
-+#include    <linux/version.h>
-+#include    <linux/param.h>
-+#include    <linux/types.h>
-+#include    <linux/interrupt.h>
-+#include    <linux/proc_fs.h>
-+#include    <linux/kthread.h>
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-+#include    <linux/semaphore.h>
-+#else
-+#include    <asm/semaphore.h>
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
-+#include    <linux/config.h>
-+#endif
-+
-+/* Net header files */
-+#include    <linux/netdevice.h>
-+#include    <linux/net.h>
-+#include    <linux/skbuff.h>
-+#include    <linux/if_ether.h>
-+#include    <linux/etherdevice.h>
-+#include    <net/sock.h>
-+#include    <linux/netlink.h>
-+#include    <linux/firmware.h>
-+#include    <linux/delay.h>
-+
-+#include    "uap_drv.h"
-+#include    "uap_fw.h"
-+
-+#include <linux/mmc/sdio.h>
-+#include <linux/mmc/sdio_ids.h>
-+#include <linux/mmc/sdio_func.h>
-+#include <linux/mmc/card.h>
-+#include "uap_sdio_mmc.h"
-+
-+#endif /* _UAP_HEADERS_H */
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_main.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_main.c
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_main.c    1970-01-01 01:00:00.000000000 +0100
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_main.c        2012-07-31 14:25:28.473230753 +0200
-@@ -0,0 +1,1815 @@
-+/** @file uap_main.c
-+  * @brief This file contains the major functions in uAP
-+  * driver. It includes init, exit etc..
-+  * This file also contains the initialization for SW,
-+  * FW and HW
-+  *
-+  * Copyright (C) 2008-2009, Marvell International Ltd.
-+  *
-+  * This software file (the "File") is distributed by Marvell International
-+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
-+  * (the "License").  You may use, redistribute and/or modify this File in
-+  * accordance with the terms and conditions of the License, a copy of which
-+  * is available along with the File in the gpl.txt file or by writing to
-+  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-+  *
-+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
-+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
-+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
-+  * this warranty disclaimer.
-+  *
-+  */
-+/**
-+  * @mainpage uAP Linux Driver
-+  *
-+  * @section overview_sec Overview
-+  *
-+  * This is Linux reference driver for Marvell uAP.
-+  *
-+  * @section copyright_sec Copyright
-+  *
-+  * Copyright (C) 2008, Marvell International Ltd.
-+  *
-+  */
-+
-+#include      "uap_headers.h"
-+
-+/**
-+ * the global variable of a pointer to uap_private
-+ * structure variable
-+ */
-+uap_private *uappriv = NULL;
-+#ifdef DEBUG_LEVEL1
-+#define DEFAULT_DEBUG_MASK    (DBG_MSG | DBG_FATAL | DBG_ERROR)
-+u32 drvdbg = DEFAULT_DEBUG_MASK;
-+#endif
-+/** Helper name */
-+char *helper_name = NULL;
-+/** Firmware name */
-+char *fw_name = NULL;
-+
-+/** Semaphore for add/remove card */
-+SEMAPHORE AddRemoveCardSem;
-+
-+/********************************************************
-+              Local Functions
-+********************************************************/
-+/**
-+ *  @brief This function send sleep confirm command to firmware
-+ *
-+ *  @param priv       A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE
-+ */
-+static int
-+uap_dnld_sleep_confirm_cmd(uap_private * priv)
-+{
-+    uap_adapter *Adapter = priv->adapter;
-+    int ret = UAP_STATUS_SUCCESS;
-+    ENTER();
-+    PRINTM(CMND, "Sleep confirm\n");
-+    Adapter->cmd_pending = TRUE;
-+    Adapter->cmd_wait_option = HostCmd_OPTION_WAITFORRSP_SLEEPCONFIRM;
-+    ret =
-+        sbi_host_to_card(priv, (u8 *) & Adapter->PSConfirmSleep,
-+                         sizeof(PS_CMD_ConfirmSleep));
-+    if (ret != UAP_STATUS_SUCCESS) {
-+        Adapter->ps_state = PS_STATE_AWAKE;
-+        Adapter->cmd_pending = FALSE;
-+        Adapter->cmd_wait_option = FALSE;
-+    }
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function process sleep confirm resp from firmware
-+ *
-+ *  @param priv       A pointer to uap_private structure
-+ *  @param resp       A pointer to resp buf
-+ *  @param resp_len   resp buf len
-+ *  @return      UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE
-+ */
-+int
-+uap_process_sleep_confirm_resp(uap_private * priv, u8 * resp, int resp_len)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    HostCmd_DS_COMMAND *cmd;
-+    uap_adapter *Adapter = priv->adapter;
-+    ENTER();
-+    PRINTM(CMND, "Sleep confirm resp\n");
-+    if (!resp_len) {
-+        PRINTM(ERROR, "Cmd Size is 0\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    cmd = (HostCmd_DS_COMMAND *) resp;
-+    cmd->Result = uap_le16_to_cpu(cmd->Result);
-+    if (cmd->Result != UAP_STATUS_SUCCESS) {
-+        PRINTM(ERROR, "HOST_CMD_APCMD_PS_SLEEP_CONFIRM fail=%x\n", cmd->Result);
-+        ret = -EFAULT;
-+    }
-+  done:
-+    if (ret == UAP_STATUS_SUCCESS)
-+        Adapter->ps_state = PS_STATE_SLEEP;
-+    else
-+        Adapter->ps_state = PS_STATE_AWAKE;
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function checks condition and prepares to
-+ *  send sleep confirm command to firmware if OK.
-+ *
-+ *  @param priv       A pointer to uap_private structure
-+ *  @return           n/a
-+ */
-+static void
-+uap_ps_cond_check(uap_private * priv)
-+{
-+    uap_adapter *Adapter = priv->adapter;
-+
-+    ENTER();
-+    if (!priv->uap_dev.cmd_sent &&
-+        !Adapter->cmd_pending && !Adapter->IntCounter) {
-+        uap_dnld_sleep_confirm_cmd(priv);
-+    } else {
-+        PRINTM(INFO, "Delay Sleep Confirm (%s%s%s)\n",
-+               (priv->uap_dev.cmd_sent) ? "D" : "",
-+               (Adapter->cmd_pending) ? "C" : "",
-+               (Adapter->IntCounter) ? "I" : "");
-+    }
-+    LEAVE();
-+}
-+
-+/**
-+ *  @brief This function add cmd to cmdQ and waiting for response
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @param skb           A pointer to the skb for process
-+ *  @param wait_option Wait option
-+ *  @return      UAP_STATUS_SUCCESS for success otherwise UAP_STATUS_FAILURE
-+ */
-+static int
-+uap_process_cmd(uap_private * priv, struct sk_buff *skb, u8 wait_option)
-+{
-+    uap_adapter *Adapter = priv->adapter;
-+    int ret = UAP_STATUS_SUCCESS;
-+    HostCmd_DS_COMMAND *cmd;
-+    u8 *headptr;
-+    ENTER();
-+    if (Adapter->HardwareStatus != HWReady) {
-+        PRINTM(ERROR, "Hw not ready, uap_process_cmd\n");
-+        kfree(skb);
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    skb->cb[0] = wait_option;
-+    headptr = skb->data;
-+    *(u16 *) & headptr[0] = uap_cpu_to_le16(skb->len);
-+    *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_CMD);
-+    cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
-+    Adapter->SeqNum++;
-+    cmd->SeqNum = uap_cpu_to_le16(Adapter->SeqNum);
-+    PRINTM(CMND, "process_cmd: %x\n", cmd->Command);
-+    DBG_HEXDUMP(CMD_D, "process_cmd", (u8 *) cmd, cmd->Size);
-+    if (!wait_option) {
-+        skb_queue_tail(&priv->adapter->cmd_queue, skb);
-+        wake_up_interruptible(&priv->MainThread.waitQ);
-+        LEAVE();
-+        return ret;
-+    }
-+    if (OS_ACQ_SEMAPHORE_BLOCK(&Adapter->CmdSem)) {
-+        PRINTM(ERROR, "Acquire semaphore error, uap_prepare_cmd\n");
-+        kfree(skb);
-+        LEAVE();
-+        return -EBUSY;
-+    }
-+    skb_queue_tail(&priv->adapter->cmd_queue, skb);
-+    Adapter->CmdWaitQWoken = FALSE;
-+    wake_up_interruptible(&priv->MainThread.waitQ);
-+    /* Sleep until response is generated by FW */
-+    if (wait_option == HostCmd_OPTION_WAITFORRSP_TIMEOUT) {
-+        if (!os_wait_interruptible_timeout
-+            (Adapter->cmdwait_q, Adapter->CmdWaitQWoken, MRVDRV_TIMER_20S)) {
-+            PRINTM(ERROR, "Cmd timeout\n");
-+            Adapter->cmd_pending = FALSE;
-+            ret = -EFAULT;
-+        }
-+    } else
-+        wait_event_interruptible(Adapter->cmdwait_q, Adapter->CmdWaitQWoken);
-+    OS_REL_SEMAPHORE(&Adapter->CmdSem);
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief Inspect the response buffer for pointers to expected TLVs
-+ *
-+ *
-+ *  @param pTlv        Pointer to the start of the TLV buffer to parse
-+ *  @param tlvBufSize  Size of the TLV buffer
-+ *  @param reqTlvType  request tlv's tlvtype
-+ *  @param ppTlv       Output parameter: Pointer to the request TLV if found
-+ *
-+ *  @return            void
-+ */
-+static void
-+uap_get_tlv_ptrs(MrvlIEtypes_Data_t * pTlv, int tlvBufSize,
-+                 u16 reqTlvType, MrvlIEtypes_Data_t ** ppTlv)
-+{
-+    MrvlIEtypes_Data_t *pCurrentTlv;
-+    int tlvBufLeft;
-+    u16 tlvType;
-+    u16 tlvLen;
-+
-+    ENTER();
-+    pCurrentTlv = pTlv;
-+    tlvBufLeft = tlvBufSize;
-+    *ppTlv = NULL;
-+    PRINTM(INFO, "uap_get_tlv: tlvBufSize = %d, reqTlvType=%x\n", tlvBufSize,
-+           reqTlvType);
-+    while (tlvBufLeft >= sizeof(MrvlIEtypesHeader_t)) {
-+        tlvType = uap_le16_to_cpu(pCurrentTlv->Header.Type);
-+        tlvLen = uap_le16_to_cpu(pCurrentTlv->Header.Len);
-+        if (reqTlvType == tlvType)
-+            *ppTlv = (MrvlIEtypes_Data_t *) pCurrentTlv;
-+        if (*ppTlv) {
-+            HEXDUMP("TLV Buf", (u8 *) * ppTlv, tlvLen);
-+            break;
-+        }
-+        tlvBufLeft -= (sizeof(pTlv->Header) + tlvLen);
-+        pCurrentTlv = (MrvlIEtypes_Data_t *) (pCurrentTlv->Data + tlvLen);
-+    }                           /* while */
-+    LEAVE();
-+}
-+
-+/**
-+ *  @brief This function get mac
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
-+ */
-+static int
-+uap_get_mac_address(uap_private * priv)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    u32 CmdSize;
-+    HostCmd_DS_COMMAND *cmd;
-+    uap_adapter *Adapter = priv->adapter;
-+    struct sk_buff *skb;
-+    MrvlIEtypes_MacAddr_t *pMacAddrTlv;
-+    MrvlIEtypes_Data_t *pTlv;
-+    u16 tlvBufSize;
-+    ENTER();
-+    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
-+    if (!skb) {
-+        PRINTM(ERROR, "No free skb\n");
-+        ret = -ENOMEM;
-+        goto done;
-+    }
-+    CmdSize =
-+        S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t);
-+    cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
-+    cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
-+    cmd->Size = uap_cpu_to_le16(CmdSize);
-+    cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_GET);
-+    pMacAddrTlv =
-+        (MrvlIEtypes_MacAddr_t *) (skb->data + INTF_HEADER_LEN + S_DS_GEN +
-+                                   sizeof(HostCmd_SYS_CONFIG));
-+    pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID);
-+    pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN);
-+    skb_put(skb, CmdSize + INTF_HEADER_LEN);
-+    if (UAP_STATUS_SUCCESS !=
-+        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
-+        PRINTM(ERROR, "Fail to process cmd SYS_CONFIGURE Query\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    if (!Adapter->CmdSize) {
-+        PRINTM(ERROR, "Cmd Size is 0\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf;
-+    cmd->Result = uap_le16_to_cpu(cmd->Result);
-+    if (cmd->Result != UAP_STATUS_SUCCESS) {
-+        PRINTM(ERROR, "uap_get_mac_address fail=%x\n", cmd->Result);
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    pTlv =
-+        (MrvlIEtypes_Data_t *) (Adapter->CmdBuf + S_DS_GEN +
-+                                sizeof(HostCmd_SYS_CONFIG));
-+    tlvBufSize = Adapter->CmdSize - S_DS_GEN - sizeof(HostCmd_SYS_CONFIG);
-+    uap_get_tlv_ptrs(pTlv, tlvBufSize, MRVL_AP_MAC_ADDRESS_TLV_ID,
-+                     (MrvlIEtypes_Data_t **) & pMacAddrTlv);
-+    if (pMacAddrTlv) {
-+        memcpy(priv->uap_dev.netdev->dev_addr, pMacAddrTlv->ApMacAddr,
-+               ETH_ALEN);
-+        HEXDUMP("Original MAC addr", priv->uap_dev.netdev->dev_addr, ETH_ALEN);
-+    }
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function checks the conditions and sends packet to device
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @param skb           A pointer to the skb for process
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+static int
-+uap_process_tx(uap_private * priv, struct sk_buff *skb)
-+{
-+    uap_adapter *Adapter = priv->adapter;
-+    int ret = UAP_STATUS_SUCCESS;
-+    TxPD *pLocalTxPD;
-+    u8 *headptr;
-+    struct sk_buff *newskb;
-+    int newheadlen;
-+    ENTER();
-+    ASSERT(skb);
-+    if (!skb) {
-+        LEAVE();
-+        return UAP_STATUS_FAILURE;
-+    }
-+    if (skb_headroom(skb) < (sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT)) {
-+        newheadlen = sizeof(TxPD) + INTF_HEADER_LEN + HEADER_ALIGNMENT;
-+        PRINTM(WARN, "Tx: Insufficient skb headroom %d\n", skb_headroom(skb));
-+        /* Insufficient skb headroom - allocate a new skb */
-+        newskb = skb_realloc_headroom(skb, newheadlen);
-+        if (unlikely(newskb == NULL)) {
-+            PRINTM(ERROR, "Tx: Cannot allocate skb\n");
-+            ret = UAP_STATUS_FAILURE;
-+            goto done;
-+        }
-+        kfree_skb(skb);
-+        skb = newskb;
-+        PRINTM(INFO, "new skb headroom %d\n", skb_headroom(skb));
-+    }
-+    /* headptr should be aligned */
-+    headptr = skb->data - sizeof(TxPD) - INTF_HEADER_LEN;
-+    headptr = (u8 *) ((u32) headptr & ~((u32) (HEADER_ALIGNMENT - 1)));
-+
-+    pLocalTxPD = (TxPD *) (headptr + INTF_HEADER_LEN);
-+    memset(pLocalTxPD, 0, sizeof(TxPD));
-+    pLocalTxPD->BssType = PKT_TYPE_MICROAP;
-+    pLocalTxPD->TxPktLength = skb->len;
-+    /* offset of actual data */
-+    pLocalTxPD->TxPktOffset = (long) skb->data - (long) pLocalTxPD;
-+    endian_convert_TxPD(pLocalTxPD);
-+    *(u16 *) & headptr[0] =
-+        uap_cpu_to_le16(skb->len + ((long) skb->data - (long) headptr));
-+    *(u16 *) & headptr[2] = uap_cpu_to_le16(MV_TYPE_DAT);
-+    ret =
-+        sbi_host_to_card(priv, headptr,
-+                         skb->len + ((long) skb->data - (long) headptr));
-+    if (ret) {
-+        PRINTM(ERROR, "uap_process_tx Error: sbi_host_to_card failed: 0x%X\n",
-+               ret);
-+        Adapter->dbg.num_tx_host_to_card_failure++;
-+        goto done;
-+    }
-+    PRINTM(DATA, "Data => FW\n");
-+    DBG_HEXDUMP(DAT_D, "Tx", headptr,
-+                MIN(skb->len + sizeof(TxPD), DATA_DUMP_LEN));
-+  done:
-+    /* Freed skb */
-+    kfree_skb(skb);
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function initializes the adapter structure
-+ *  and set default value to the member of adapter.
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+static int
-+uap_init_sw(uap_private * priv)
-+{
-+    uap_adapter *Adapter = priv->adapter;
-+
-+    ENTER();
-+
-+    if (!(Adapter->CmdBuf = kmalloc(MRVDRV_SIZE_OF_CMD_BUFFER, GFP_KERNEL))) {
-+        PRINTM(INFO, "Failed to allocate command buffer!\n");
-+        LEAVE();
-+        return UAP_STATUS_FAILURE;
-+    }
-+
-+    Adapter->cmd_pending = FALSE;
-+    Adapter->CmdWaitQWoken = FALSE;
-+    Adapter->ps_state = PS_STATE_AWAKE;
-+    Adapter->WakeupTries = 0;
-+
-+    memset(&Adapter->PSConfirmSleep, 0, sizeof(PS_CMD_ConfirmSleep));
-+        /** SDIO header */
-+    Adapter->PSConfirmSleep.SDLen =
-+        uap_cpu_to_le16(sizeof(PS_CMD_ConfirmSleep));
-+    Adapter->PSConfirmSleep.SDType = uap_cpu_to_le16(MV_TYPE_CMD);
-+    Adapter->PSConfirmSleep.SeqNum = 0;
-+    Adapter->PSConfirmSleep.Command = uap_cpu_to_le16(HOST_CMD_SLEEP_CONFIRM);
-+    Adapter->PSConfirmSleep.Size = uap_cpu_to_le16(sizeof(HostCmd_DS_GEN));
-+    Adapter->PSConfirmSleep.Result = 0;
-+
-+    init_waitqueue_head(&Adapter->cmdwait_q);
-+    OS_INIT_SEMAPHORE(&Adapter->CmdSem);
-+
-+    skb_queue_head_init(&Adapter->tx_queue);
-+    skb_queue_head_init(&Adapter->cmd_queue);
-+
-+    /* Status variable */
-+    Adapter->HardwareStatus = HWInitializing;
-+
-+    /* PnP support */
-+    Adapter->SurpriseRemoved = FALSE;
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-+    Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL,
-+                                           NL_MULTICAST_GROUP, NULL,
-+                                           THIS_MODULE);
-+#else
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-+    Adapter->nl_sk = netlink_kernel_create(NETLINK_MARVELL,
-+                                           NL_MULTICAST_GROUP, NULL, NULL,
-+                                           THIS_MODULE);
-+#else
-+    Adapter->nl_sk = netlink_kernel_create(&init_net, NETLINK_MARVELL,
-+                                           NL_MULTICAST_GROUP, NULL, NULL,
-+                                           THIS_MODULE);
-+#endif
-+#endif
-+    if (!Adapter->nl_sk) {
-+        PRINTM(ERROR,
-+               "Could not initialize netlink event passing mechanism!\n");
-+    }
-+    LEAVE();
-+    return UAP_STATUS_SUCCESS;
-+}
-+
-+/**
-+ *  @brief This function sends FUNC_INIT command to firmware
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
-+ */
-+static int
-+uap_func_init(uap_private * priv)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    u32 CmdSize;
-+    HostCmd_DS_GEN *cmd;
-+    uap_adapter *Adapter = priv->adapter;
-+    struct sk_buff *skb;
-+    ENTER();
-+    if (Adapter->HardwareStatus != HWReady) {
-+        PRINTM(ERROR, "uap_func_init:Hardware is not ready!\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
-+    if (!skb) {
-+        PRINTM(ERROR, "No free skb\n");
-+        ret = -ENOMEM;
-+        goto done;
-+    }
-+    CmdSize = sizeof(HostCmd_DS_GEN);
-+    cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
-+    cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_INIT);
-+    cmd->Size = uap_cpu_to_le16(CmdSize);
-+    skb_put(skb, CmdSize + INTF_HEADER_LEN);
-+    PRINTM(CMND, "HostCmd_CMD_FUNC_INIT\n");
-+    if (UAP_STATUS_SUCCESS !=
-+        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
-+        PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_INIT\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function sends FUNC_SHUTDOWN command to firmware
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
-+ */
-+static int __exit
-+uap_func_shutdown(uap_private * priv)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    u32 CmdSize;
-+    HostCmd_DS_GEN *cmd;
-+    uap_adapter *Adapter = priv->adapter;
-+    struct sk_buff *skb;
-+    ENTER();
-+    if (Adapter->HardwareStatus != HWReady) {
-+        PRINTM(ERROR, "uap_func_shutdown:Hardware is not ready!\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
-+    if (!skb) {
-+        PRINTM(ERROR, "No free skb\n");
-+        ret = -ENOMEM;
-+        goto done;
-+    }
-+    CmdSize = sizeof(HostCmd_DS_GEN);
-+    cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
-+    cmd->Command = uap_cpu_to_le16(HostCmd_CMD_FUNC_SHUTDOWN);
-+    cmd->Size = uap_cpu_to_le16(CmdSize);
-+    skb_put(skb, CmdSize + INTF_HEADER_LEN);
-+    PRINTM(CMND, "HostCmd_CMD_FUNC_SHUTDOWN\n");
-+    if (UAP_STATUS_SUCCESS !=
-+        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
-+        PRINTM(ERROR, "Fail to process cmd HostCmd_CMD_FUNC_SHUTDOWN\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function initializes firmware
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+static int
-+uap_init_fw(uap_private * priv)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    ENTER();
-+    sbi_disable_host_int(priv);
-+    /* Check if firmware is already running */
-+    if (sbi_check_fw_status(priv, 1) == UAP_STATUS_SUCCESS) {
-+        PRINTM(MSG, "UAP FW already running! Skip FW download\n");
-+    } else {
-+        if ((ret = request_firmware(&priv->fw_helper, helper_name,
-+                                    priv->hotplug_device)) < 0) {
-+            PRINTM(FATAL,
-+                   "request_firmware() failed (helper), error code = %#x\n",
-+                   ret);
-+            goto done;
-+        }
-+
-+        /* Download the helper */
-+        ret = sbi_prog_helper(priv);
-+
-+        if (ret) {
-+            PRINTM(FATAL,
-+                   "Bootloader in invalid state! Helper download failed!\n");
-+            ret = UAP_STATUS_FAILURE;
-+            goto done;
-+        }
-+        if ((ret = request_firmware(&priv->firmware, fw_name,
-+                                    priv->hotplug_device)) < 0) {
-+            PRINTM(FATAL, "request_firmware() failed, error code = %#x\n", ret);
-+            goto done;
-+        }
-+
-+        /* Download the main firmware via the helper firmware */
-+        if (sbi_prog_fw_w_helper(priv)) {
-+            PRINTM(FATAL, "UAP FW download failed!\n");
-+            ret = UAP_STATUS_FAILURE;
-+            goto done;
-+        }
-+        /* Check if the firmware is downloaded successfully or not */
-+        if (sbi_check_fw_status(priv, MAX_FIRMWARE_POLL_TRIES) ==
-+            UAP_STATUS_FAILURE) {
-+            PRINTM(FATAL, "FW failed to be active in time!\n");
-+            ret = UAP_STATUS_FAILURE;
-+            goto done;
-+        }
-+        PRINTM(MSG, "UAP FW is active\n");
-+    }
-+    sbi_enable_host_int(priv);
-+    priv->adapter->HardwareStatus = HWReady;
-+    if (uap_func_init(priv) != UAP_STATUS_SUCCESS) {
-+        ret = UAP_STATUS_FAILURE;
-+        goto done;
-+    }
-+  done:
-+    if (priv->fw_helper)
-+        release_firmware(priv->fw_helper);
-+    if (priv->firmware)
-+        release_firmware(priv->firmware);
-+    LEAVE();
-+    return ret;
-+
-+}
-+
-+/**
-+ *  @brief This function frees the structure of adapter
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      n/a
-+ */
-+static void
-+uap_free_adapter(uap_private * priv)
-+{
-+    uap_adapter *Adapter = priv->adapter;
-+
-+    ENTER();
-+
-+    if (Adapter) {
-+        if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) {
-+            sock_release((Adapter->nl_sk)->sk_socket);
-+            Adapter->nl_sk = NULL;
-+        }
-+        if (Adapter->CmdBuf)
-+            kfree(Adapter->CmdBuf);
-+        skb_queue_purge(&priv->adapter->tx_queue);
-+        skb_queue_purge(&priv->adapter->cmd_queue);
-+        /* Free the adapter object itself */
-+        kfree(Adapter);
-+        priv->adapter = NULL;
-+    }
-+
-+    LEAVE();
-+}
-+
-+/**
-+ *  @brief This function handles the major job in uap driver.
-+ *  it handles the event generated by firmware, rx data received
-+ *  from firmware and tx data sent from kernel.
-+ *
-+ *  @param data    A pointer to uap_thread structure
-+ *  @return        BT_STATUS_SUCCESS
-+ */
-+static int
-+uap_service_main_thread(void *data)
-+{
-+    uap_thread *thread = data;
-+    uap_private *priv = thread->priv;
-+    uap_adapter *Adapter = priv->adapter;
-+    wait_queue_t wait;
-+    u8 ireg = 0;
-+    struct sk_buff *skb;
-+    ENTER();
-+    uap_activate_thread(thread);
-+    init_waitqueue_entry(&wait, current);
-+    current->flags |= PF_NOFREEZE;
-+
-+    for (;;) {
-+        add_wait_queue(&thread->waitQ, &wait);
-+        OS_SET_THREAD_STATE(TASK_INTERRUPTIBLE);
-+        if ((Adapter->WakeupTries) ||
-+            (!Adapter->IntCounter && Adapter->ps_state == PS_STATE_PRE_SLEEP) ||
-+            (!priv->adapter->IntCounter
-+             && (priv->uap_dev.data_sent ||
-+                 skb_queue_empty(&priv->adapter->tx_queue))
-+             && (priv->uap_dev.cmd_sent || Adapter->cmd_pending ||
-+                 skb_queue_empty(&priv->adapter->cmd_queue))
-+            )) {
-+            PRINTM(INFO, "Main: Thread sleeping...\n");
-+            schedule();
-+        }
-+        OS_SET_THREAD_STATE(TASK_RUNNING);
-+        remove_wait_queue(&thread->waitQ, &wait);
-+        if (kthread_should_stop() || Adapter->SurpriseRemoved) {
-+            PRINTM(INFO, "main-thread: break from main thread: "
-+                   "SurpriseRemoved=0x%x\n", Adapter->SurpriseRemoved);
-+            /* Cancel pending command */
-+            if (Adapter->cmd_pending == TRUE) {
-+                /* Wake up cmd Q */
-+                Adapter->CmdWaitQWoken = TRUE;
-+                wake_up_interruptible(&Adapter->cmdwait_q);
-+            }
-+            break;
-+        }
-+
-+        PRINTM(INFO, "Main: Thread waking up...\n");
-+        if (priv->adapter->IntCounter) {
-+            OS_INT_DISABLE;
-+            Adapter->IntCounter = 0;
-+            OS_INT_RESTORE;
-+            sbi_get_int_status(priv, &ireg);
-+        } else if ((priv->adapter->ps_state == PS_STATE_SLEEP) &&
-+                   (!skb_queue_empty(&priv->adapter->cmd_queue) ||
-+                    !skb_queue_empty(&priv->adapter->tx_queue))) {
-+            priv->adapter->WakeupTries++;
-+            PRINTM(CMND, "%lu : Wakeup device...\n", os_time_get());
-+            sbi_wakeup_firmware(priv);
-+            continue;
-+        }
-+        if (Adapter->ps_state == PS_STATE_PRE_SLEEP)
-+            uap_ps_cond_check(priv);
-+
-+        /* The PS state is changed during processing of Sleep Request event
-+           above */
-+        if ((Adapter->ps_state == PS_STATE_SLEEP) ||
-+            (Adapter->ps_state == PS_STATE_PRE_SLEEP))
-+            continue;
-+        /* Execute the next command */
-+        if (!priv->uap_dev.cmd_sent && !Adapter->cmd_pending &&
-+            (Adapter->HardwareStatus == HWReady)) {
-+            if (!skb_queue_empty(&priv->adapter->cmd_queue)) {
-+                skb = skb_dequeue(&priv->adapter->cmd_queue);
-+                if (skb) {
-+                    Adapter->CmdSize = 0;
-+                    Adapter->cmd_pending = TRUE;
-+                    Adapter->cmd_wait_option = skb->cb[0];
-+                    if (sbi_host_to_card(priv, skb->data, skb->len)) {
-+                        PRINTM(ERROR, "Cmd:sbi_host_to_card failed!\n");
-+                        Adapter->cmd_pending = FALSE;
-+                        Adapter->dbg.num_cmd_host_to_card_failure++;
-+                        /* Wake up cmd Q */
-+                        Adapter->CmdWaitQWoken = TRUE;
-+                        wake_up_interruptible(&Adapter->cmdwait_q);
-+                    } else {
-+                        if (Adapter->cmd_wait_option ==
-+                            HostCmd_OPTION_WAITFORSEND) {
-+                            /* Wake up cmd Q */
-+                            Adapter->CmdWaitQWoken = TRUE;
-+                            wake_up_interruptible(&Adapter->cmdwait_q);
-+                            Adapter->cmd_wait_option = FALSE;
-+                        }
-+                    }
-+                    kfree_skb(skb);
-+                }
-+            }
-+        }
-+        if (!priv->uap_dev.data_sent && (Adapter->HardwareStatus == HWReady)) {
-+            if (!skb_queue_empty(&priv->adapter->tx_queue)) {
-+                skb = skb_dequeue(&priv->adapter->tx_queue);
-+                if (skb) {
-+                    if (uap_process_tx(priv, skb)) {
-+                        priv->stats.tx_dropped++;
-+                        priv->stats.tx_errors++;
-+                        os_start_queue(priv);
-+                    } else {
-+                        priv->stats.tx_packets++;
-+                        priv->stats.tx_bytes += skb->len;
-+                    }
-+
-+                }
-+            }
-+        }
-+    }
-+    uap_deactivate_thread(thread);
-+    LEAVE();
-+    return UAP_STATUS_SUCCESS;
-+}
-+
-+/**
-+ *  @brief uap hostcmd ioctl handler
-+ *
-+ *  @param dev      A pointer to net_device structure
-+ *  @param req      A pointer to ifreq structure
-+ *  @return         UAP_STATUS_SUCCESS --success, otherwise fail
-+ */
-+/*********  format of ifr_data *************/
-+/*    buf_len + Hostcmd_body             */
-+/*    buf_len: 4 bytes                     */
-+/*             the length of the buf which */
-+/*             can be used to return data  */
-+/*             to application            */
-+/*    Hostcmd_body                       */
-+/*******************************************/
-+static int
-+uap_hostcmd_ioctl(struct net_device *dev, struct ifreq *req)
-+{
-+    u32 buf_len;
-+    HostCmd_HEADER head;
-+    uap_private *priv = (uap_private *) netdev_priv(dev);
-+    uap_adapter *Adapter = priv->adapter;
-+    int ret = UAP_STATUS_SUCCESS;
-+    struct sk_buff *skb;
-+
-+    ENTER();
-+
-+    /* Sanity check */
-+    if (req->ifr_data == NULL) {
-+        PRINTM(ERROR, "uap_hostcmd_ioctl() corrupt data\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    if (copy_from_user(&buf_len, req->ifr_data, sizeof(buf_len))) {
-+        PRINTM(ERROR, "Copy from user failed\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    memset(&head, 0, sizeof(HostCmd_HEADER));
-+    /* Get the command size from user space */
-+    if (copy_from_user
-+        (&head, req->ifr_data + sizeof(buf_len), sizeof(HostCmd_HEADER))) {
-+        PRINTM(ERROR, "Copy from user failed\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    head.Size = uap_le16_to_cpu(head.Size);
-+    if (head.Size > MRVDRV_SIZE_OF_CMD_BUFFER) {
-+        PRINTM(ERROR, "CmdSize too big=%d\n", head.Size);
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    PRINTM(CMND, "ioctl: hostcmd=%x, size=%d,buf_len=%d\n", head.Command,
-+           head.Size, buf_len);
-+    skb = dev_alloc_skb(head.Size + INTF_HEADER_LEN);
-+    if (!skb) {
-+        PRINTM(ERROR, "No free skb\n");
-+        LEAVE();
-+        return -ENOMEM;
-+    }
-+
-+    /* Get the command from user space */
-+    if (copy_from_user
-+        (skb->data + INTF_HEADER_LEN, req->ifr_data + sizeof(buf_len),
-+         head.Size)) {
-+        PRINTM(ERROR, "Copy from user failed\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    skb_put(skb, head.Size + INTF_HEADER_LEN);
-+    if (UAP_STATUS_SUCCESS !=
-+        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) {
-+        PRINTM(ERROR, "Fail to process cmd\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    if (!Adapter->CmdSize) {
-+        PRINTM(ERROR, "Cmd Size is 0\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    if (Adapter->CmdSize > buf_len) {
-+        PRINTM(ERROR, "buf_len is too small\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    /* Copy to user */
-+    if (copy_to_user
-+        (req->ifr_data + sizeof(buf_len), Adapter->CmdBuf, Adapter->CmdSize)) {
-+        PRINTM(ERROR, "Copy to user failed!\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief uap power mode ioctl handler
-+ *
-+ *  @param dev      A pointer to net_device structure
-+ *  @param req      A pointer to ifreq structure
-+ *  @return         UAP_STATUS_SUCCESS --success, otherwise fail
-+ */
-+static int
-+uap_power_mode_ioctl(struct net_device *dev, struct ifreq *req)
-+{
-+    ps_mgmt pm_cfg;
-+    int ret = UAP_STATUS_SUCCESS;
-+    uap_private *priv = (uap_private *) netdev_priv(dev);
-+    uap_adapter *Adapter = priv->adapter;
-+    struct sk_buff *skb = NULL;
-+    HostCmd_DS_COMMAND *cmd;
-+    u32 CmdSize;
-+    u8 *tlv = NULL;
-+    MrvlIEtypes_sleep_param_t *sleep_tlv = NULL;
-+    MrvlIEtypes_inact_sleep_param_t *inact_tlv = NULL;
-+    u16 tlv_buf_left = 0;
-+    MrvlIEtypesHeader_t *tlvbuf = NULL;
-+    u16 tlv_type = 0;
-+    u16 tlv_len = 0;
-+
-+    ENTER();
-+
-+    /* Sanity check */
-+    if (req->ifr_data == NULL) {
-+        PRINTM(ERROR, "uap_power_mode_ioctl() corrupt data\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+
-+    memset(&pm_cfg, 0, sizeof(ps_mgmt));
-+    if (copy_from_user(&pm_cfg, req->ifr_data, sizeof(ps_mgmt))) {
-+        PRINTM(ERROR, "Copy from user failed\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    PRINTM(CMND,
-+           "ioctl power: flag=0x%x ps_mode=%d ctrl_bitmap=%d min_sleep=%d max_sleep=%d "
-+           "inact_to=%d min_awake=%d max_awake=%d\n", pm_cfg.flags,
-+           (int) pm_cfg.ps_mode, (int) pm_cfg.sleep_param.ctrl_bitmap,
-+           (int) pm_cfg.sleep_param.min_sleep,
-+           (int) pm_cfg.sleep_param.max_sleep,
-+           (int) pm_cfg.inact_param.inactivity_to,
-+           (int) pm_cfg.inact_param.min_awake,
-+           (int) pm_cfg.inact_param.max_awake);
-+
-+    if (pm_cfg.
-+        flags & ~(PS_FLAG_PS_MODE | PS_FLAG_SLEEP_PARAM |
-+                  PS_FLAG_INACT_SLEEP_PARAM)) {
-+        PRINTM(ERROR, "Invalid parameter: flags = 0x%x\n", pm_cfg.flags);
-+        ret = -EINVAL;
-+        goto done;
-+    }
-+    if (pm_cfg.ps_mode > PS_MODE_INACTIVITY) {
-+        PRINTM(ERROR, "Invalid parameter: ps_mode = %d\n", (int) pm_cfg.flags);
-+        ret = -EINVAL;
-+        goto done;
-+    }
-+
-+    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
-+    if (!skb) {
-+        PRINTM(INFO, "No free skb\n");
-+        ret = -ENOMEM;
-+        goto done;
-+    }
-+
-+    CmdSize = S_DS_GEN + sizeof(HostCmd_DS_POWER_MGMT_EXT);
-+
-+    cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
-+    cmd->Command = uap_cpu_to_le16(HOST_CMD_POWER_MGMT_EXT);
-+    if (!pm_cfg.flags) {
-+        cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_GET);
-+    } else {
-+        cmd->params.pm_cfg.action = uap_cpu_to_le16(ACTION_SET);
-+        cmd->params.pm_cfg.power_mode = uap_cpu_to_le16(pm_cfg.ps_mode);
-+        tlv = (u8 *) & cmd->params.pm_cfg + sizeof(HostCmd_DS_POWER_MGMT_EXT);
-+
-+        if ((pm_cfg.ps_mode) && (pm_cfg.flags & PS_FLAG_SLEEP_PARAM)) {
-+            sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlv;
-+            sleep_tlv->header.Type = uap_cpu_to_le16(TLV_TYPE_AP_SLEEP_PARAM);
-+            sleep_tlv->header.Len =
-+                uap_cpu_to_le16(sizeof(MrvlIEtypes_sleep_param_t) -
-+                                sizeof(MrvlIEtypesHeader_t));
-+            sleep_tlv->ctrl_bitmap =
-+                uap_cpu_to_le32(pm_cfg.sleep_param.ctrl_bitmap);
-+            sleep_tlv->min_sleep =
-+                uap_cpu_to_le32(pm_cfg.sleep_param.min_sleep);
-+            sleep_tlv->max_sleep =
-+                uap_cpu_to_le32(pm_cfg.sleep_param.max_sleep);
-+            CmdSize += sizeof(MrvlIEtypes_sleep_param_t);
-+            tlv += sizeof(MrvlIEtypes_sleep_param_t);
-+        }
-+        if ((pm_cfg.ps_mode == PS_MODE_INACTIVITY) &&
-+            (pm_cfg.flags & PS_FLAG_INACT_SLEEP_PARAM)) {
-+            inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlv;
-+            inact_tlv->header.Type =
-+                uap_cpu_to_le16(TLV_TYPE_AP_INACT_SLEEP_PARAM);
-+            inact_tlv->header.Len =
-+                uap_cpu_to_le16(sizeof(MrvlIEtypes_inact_sleep_param_t) -
-+                                sizeof(MrvlIEtypesHeader_t));
-+            inact_tlv->inactivity_to =
-+                uap_cpu_to_le32(pm_cfg.inact_param.inactivity_to);
-+            inact_tlv->min_awake =
-+                uap_cpu_to_le32(pm_cfg.inact_param.min_awake);
-+            inact_tlv->max_awake =
-+                uap_cpu_to_le32(pm_cfg.inact_param.max_awake);
-+            CmdSize += sizeof(MrvlIEtypes_inact_sleep_param_t);
-+            tlv += sizeof(MrvlIEtypes_inact_sleep_param_t);
-+        }
-+    }
-+    cmd->Size = uap_cpu_to_le16(CmdSize);
-+    skb_put(skb, CmdSize + INTF_HEADER_LEN);
-+    if (UAP_STATUS_SUCCESS !=
-+        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP)) {
-+        PRINTM(ERROR, "Fail to process cmd POWER_MODE\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    if (!Adapter->CmdSize) {
-+        PRINTM(ERROR, "Cmd Size is 0\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf;
-+    cmd->Result = uap_le16_to_cpu(cmd->Result);
-+    if (cmd->Result != UAP_STATUS_SUCCESS) {
-+        PRINTM(ERROR, "HOST_CMD_APCMD_POWER_MODE fail=%x\n", cmd->Result);
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    if (pm_cfg.flags) {
-+        Adapter->psmode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode);
-+    } else {
-+        pm_cfg.flags = PS_FLAG_PS_MODE;
-+        pm_cfg.ps_mode = uap_le16_to_cpu(cmd->params.pm_cfg.power_mode);
-+        tlv_buf_left =
-+            cmd->Size - (sizeof(HostCmd_DS_POWER_MGMT_EXT) + S_DS_GEN);
-+        tlvbuf =
-+            (MrvlIEtypesHeader_t *) ((u8 *) & cmd->params.pm_cfg +
-+                                     sizeof(HostCmd_DS_POWER_MGMT_EXT));
-+        while (tlv_buf_left >= sizeof(MrvlIEtypesHeader_t)) {
-+            tlv_type = uap_le16_to_cpu(tlvbuf->Type);
-+            tlv_len = uap_le16_to_cpu(tlvbuf->Len);
-+            switch (tlv_type) {
-+            case TLV_TYPE_AP_SLEEP_PARAM:
-+                sleep_tlv = (MrvlIEtypes_sleep_param_t *) tlvbuf;
-+                pm_cfg.flags |= PS_FLAG_SLEEP_PARAM;
-+                pm_cfg.sleep_param.ctrl_bitmap =
-+                    uap_le32_to_cpu(sleep_tlv->ctrl_bitmap);
-+                pm_cfg.sleep_param.min_sleep =
-+                    uap_le32_to_cpu(sleep_tlv->min_sleep);
-+                pm_cfg.sleep_param.max_sleep =
-+                    uap_le32_to_cpu(sleep_tlv->max_sleep);
-+                break;
-+            case TLV_TYPE_AP_INACT_SLEEP_PARAM:
-+                inact_tlv = (MrvlIEtypes_inact_sleep_param_t *) tlvbuf;
-+                pm_cfg.flags |= PS_FLAG_INACT_SLEEP_PARAM;
-+                pm_cfg.inact_param.inactivity_to =
-+                    uap_le32_to_cpu(inact_tlv->inactivity_to);
-+                pm_cfg.inact_param.min_awake =
-+                    uap_le32_to_cpu(inact_tlv->min_awake);
-+                pm_cfg.inact_param.max_awake =
-+                    uap_le32_to_cpu(inact_tlv->max_awake);
-+                break;
-+            }
-+            tlv_buf_left -= tlv_len + sizeof(MrvlIEtypesHeader_t);
-+            tlvbuf =
-+                (MrvlIEtypesHeader_t *) ((u8 *) tlvbuf + tlv_len +
-+                                         sizeof(MrvlIEtypesHeader_t));
-+        }
-+        /* Copy to user */
-+        if (copy_to_user(req->ifr_data, &pm_cfg, sizeof(ps_mgmt))) {
-+            PRINTM(ERROR, "Copy to user failed!\n");
-+            LEAVE();
-+            return -EFAULT;
-+        }
-+    }
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function send bss_stop command to firmware
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
-+ */
-+static int
-+uap_bss_stop(uap_private * priv)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    u32 CmdSize;
-+    HostCmd_DS_GEN *cmd;
-+    uap_adapter *Adapter = priv->adapter;
-+    struct sk_buff *skb;
-+    ENTER();
-+    if (Adapter->HardwareStatus != HWReady) {
-+        PRINTM(ERROR, "uap_bss_stop:Hardware is not ready!\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
-+    if (!skb) {
-+        PRINTM(ERROR, "No free skb\n");
-+        ret = -ENOMEM;
-+        goto done;
-+    }
-+    CmdSize = sizeof(HostCmd_DS_GEN);
-+    cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
-+    cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_BSS_STOP);
-+    cmd->Size = uap_cpu_to_le16(CmdSize);
-+    skb_put(skb, CmdSize + INTF_HEADER_LEN);
-+    PRINTM(CMND, "APCMD_BSS_STOP\n");
-+    if (UAP_STATUS_SUCCESS !=
-+        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
-+        PRINTM(ERROR, "Fail to process cmd BSS_STOP\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/********************************************************
-+              Global Functions
-+********************************************************/
-+/**
-+ *  @brief This function send soft_reset command to firmware
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS on success, otherwise failure code
-+ */
-+int
-+uap_soft_reset(uap_private * priv)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    u32 CmdSize;
-+    HostCmd_DS_GEN *cmd;
-+    uap_adapter *Adapter = priv->adapter;
-+    struct sk_buff *skb;
-+    ENTER();
-+    ret = uap_bss_stop(priv);
-+    if (ret != UAP_STATUS_SUCCESS)
-+        goto done;
-+    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
-+    if (!skb) {
-+        PRINTM(ERROR, "No free skb\n");
-+        ret = -ENOMEM;
-+        goto done;
-+    }
-+    CmdSize = sizeof(HostCmd_DS_GEN);
-+    cmd = (HostCmd_DS_GEN *) (skb->data + INTF_HEADER_LEN);
-+    cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SOFT_RESET);
-+    cmd->Size = uap_cpu_to_le16(CmdSize);
-+    skb_put(skb, CmdSize + INTF_HEADER_LEN);
-+    PRINTM(CMND, "APCMD_SOFT_RESET\n");
-+    if (UAP_STATUS_SUCCESS !=
-+        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORSEND)) {
-+        PRINTM(ERROR, "Fail to process cmd SOFT_RESET\n");
-+        ret = -EFAULT;
-+        goto done;
-+    }
-+    Adapter->SurpriseRemoved = TRUE;
-+    /* delay to allow hardware complete reset */
-+    os_sched_timeout(5);
-+    if (priv->MediaConnected == TRUE) {
-+        os_stop_queue(priv);
-+        os_carrier_off(priv);
-+        priv->MediaConnected = FALSE;
-+    }
-+    Adapter->CmdSize = 0;
-+    Adapter->CmdWaitQWoken = TRUE;
-+    wake_up_interruptible(&Adapter->cmdwait_q);
-+    skb_queue_purge(&priv->adapter->tx_queue);
-+    skb_queue_purge(&priv->adapter->cmd_queue);
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function processes received packet and forwards it
-+ *  to kernel/upper layer
-+ *
-+ *  @param priv    A pointer to uap_private
-+ *  @param skb     A pointer to skb which includes the received packet
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+int
-+uap_process_rx_packet(uap_private * priv, struct sk_buff *skb)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    RxPD *pRxPD;
-+    ENTER();
-+    priv->adapter->ps_state = PS_STATE_AWAKE;
-+    pRxPD = (RxPD *) skb->data;
-+    endian_convert_RxPD(pRxPD);
-+    DBG_HEXDUMP(DAT_D, "Rx", skb->data, MIN(skb->len, DATA_DUMP_LEN));
-+    skb_pull(skb, pRxPD->RxPktOffset);
-+    priv->stats.rx_packets++;
-+    priv->stats.rx_bytes += skb->len;
-+    os_upload_rx_packet(priv, skb);
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function opens the network device
-+ *
-+ *  @param dev     A pointer to net_device structure
-+ *  @return        UAP_STATUS_SUCCESS
-+ */
-+static int
-+uap_open(struct net_device *dev)
-+{
-+    uap_private *priv = (uap_private *) (uap_private *) netdev_priv(dev);
-+    uap_adapter *Adapter = priv->adapter;
-+    int i = 0;
-+
-+    ENTER();
-+
-+    /* On some systems the device open handler will be called before HW ready. */
-+    /* Use the following flag check and wait function to work around the issue. */
-+    while ((Adapter->HardwareStatus != HWReady) &&
-+           (i < MAX_WAIT_DEVICE_READY_COUNT)) {
-+        i++;
-+        os_sched_timeout(100);
-+    }
-+    if (i >= MAX_WAIT_DEVICE_READY_COUNT) {
-+        PRINTM(FATAL, "HW not ready, uap_open() return failure\n");
-+        LEAVE();
-+        return UAP_STATUS_FAILURE;
-+    }
-+
-+    if (MODULE_GET == 0)
-+        return UAP_STATUS_FAILURE;
-+
-+    priv->open = TRUE;
-+    if (priv->MediaConnected == TRUE) {
-+        os_carrier_on(priv);
-+        os_start_queue(priv);
-+    } else {
-+        os_stop_queue(priv);
-+        os_carrier_off(priv);
-+    }
-+    LEAVE();
-+    return UAP_STATUS_SUCCESS;
-+}
-+
-+/**
-+ *  @brief This function closes the network device
-+ *
-+ *  @param dev     A pointer to net_device structure
-+ *  @return        UAP_STATUS_SUCCESS
-+ */
-+static int
-+uap_close(struct net_device *dev)
-+{
-+    uap_private *priv = (uap_private *) netdev_priv(dev);
-+
-+    ENTER();
-+    skb_queue_purge(&priv->adapter->tx_queue);
-+    os_stop_queue(priv);
-+    os_carrier_off(priv);
-+
-+    MODULE_PUT;
-+    priv->open = FALSE;
-+    LEAVE();
-+    return UAP_STATUS_SUCCESS;
-+}
-+
-+/**
-+ *  @brief This function returns the network statistics
-+ *
-+ *  @param dev     A pointer to uap_private structure
-+ *  @return        A pointer to net_device_stats structure
-+ */
-+static struct net_device_stats *
-+uap_get_stats(struct net_device *dev)
-+{
-+    uap_private *priv = (uap_private *) netdev_priv(dev);
-+
-+    return &priv->stats;
-+}
-+
-+/**
-+ *  @brief This function sets the MAC address to firmware.
-+ *
-+ *  @param dev     A pointer to uap_private structure
-+ *  @param addr    MAC address to set
-+ *  @return        UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+static int
-+uap_set_mac_address(struct net_device *dev, void *addr)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    uap_private *priv = (uap_private *) netdev_priv(dev);
-+    struct sockaddr *pHwAddr = (struct sockaddr *) addr;
-+    u32 CmdSize;
-+    HostCmd_DS_COMMAND *cmd;
-+    MrvlIEtypes_MacAddr_t *pMacAddrTlv;
-+    uap_adapter *Adapter = priv->adapter;
-+    struct sk_buff *skb;
-+
-+    ENTER();
-+
-+    /* Dump MAC address */
-+    DBG_HEXDUMP(CMD_D, "Original MAC addr", dev->dev_addr, ETH_ALEN);
-+    DBG_HEXDUMP(CMD_D, "New MAC addr", pHwAddr->sa_data, ETH_ALEN);
-+    if (priv->open && (priv->MediaConnected == TRUE)) {
-+        os_carrier_on(priv);
-+        os_start_queue(priv);
-+    }
-+    skb = dev_alloc_skb(MRVDRV_SIZE_OF_CMD_BUFFER);
-+    if (!skb) {
-+        PRINTM(ERROR, "No free skb\n");
-+        LEAVE();
-+        return -ENOMEM;
-+    }
-+    CmdSize =
-+        S_DS_GEN + sizeof(HostCmd_SYS_CONFIG) + sizeof(MrvlIEtypes_MacAddr_t);
-+    cmd = (HostCmd_DS_COMMAND *) (skb->data + INTF_HEADER_LEN);
-+    cmd->Command = uap_cpu_to_le16(HOST_CMD_APCMD_SYS_CONFIGURE);
-+    cmd->Size = uap_cpu_to_le16(CmdSize);
-+    cmd->params.sys_config.Action = uap_cpu_to_le16(ACTION_SET);
-+    pMacAddrTlv =
-+        (MrvlIEtypes_MacAddr_t *) ((u8 *) cmd + S_DS_GEN +
-+                                   sizeof(HostCmd_SYS_CONFIG));
-+    pMacAddrTlv->Header.Type = uap_cpu_to_le16(MRVL_AP_MAC_ADDRESS_TLV_ID);
-+    pMacAddrTlv->Header.Len = uap_cpu_to_le16(ETH_ALEN);
-+    memcpy(pMacAddrTlv->ApMacAddr, pHwAddr->sa_data, ETH_ALEN);
-+    skb_put(skb, CmdSize + INTF_HEADER_LEN);
-+    PRINTM(CMND, "set_mac_address\n");
-+    if (UAP_STATUS_SUCCESS !=
-+        uap_process_cmd(priv, skb, HostCmd_OPTION_WAITFORRSP_TIMEOUT)) {
-+        PRINTM(ERROR, "Fail to set mac address\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    if (!Adapter->CmdSize) {
-+        PRINTM(ERROR, "Cmd Size is 0\n");
-+        LEAVE();
-+        return -EFAULT;
-+    }
-+    cmd = (HostCmd_DS_COMMAND *) Adapter->CmdBuf;
-+    cmd->Result = uap_cpu_to_le16(cmd->Result);
-+    if (cmd->Result != UAP_STATUS_SUCCESS) {
-+        PRINTM(ERROR, "set mac addrress fail,cmd result=%x\n", cmd->Result);
-+        ret = -EFAULT;
-+    } else
-+        memcpy(dev->dev_addr, pHwAddr->sa_data, ETH_ALEN);
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function handles the timeout of packet
-+ *  transmission
-+ *
-+ *  @param dev     A pointer to net_device structure
-+ *  @return        n/a
-+ */
-+static void
-+uap_tx_timeout(struct net_device *dev)
-+{
-+    uap_private *priv = (uap_private *) netdev_priv(dev);
-+
-+    ENTER();
-+
-+    PRINTM(DATA, "Tx timeout\n");
-+    UpdateTransStart(dev);
-+    priv->num_tx_timeout++;
-+    priv->adapter->IntCounter++;
-+    wake_up_interruptible(&priv->MainThread.waitQ);
-+
-+    LEAVE();
-+}
-+
-+/**
-+ *  @brief This function handles packet transmission
-+ *
-+ *  @param skb     A pointer to sk_buff structure
-+ *  @param dev     A pointer to net_device structure
-+ *  @return        UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+static int
-+uap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+    uap_private *priv = (uap_private *) netdev_priv(dev);
-+    int ret = UAP_STATUS_SUCCESS;
-+
-+    ENTER();
-+    PRINTM(DATA, "Data <= kernel\n");
-+    DBG_HEXDUMP(DAT_D, "Tx", skb->data, MIN(skb->len, DATA_DUMP_LEN));
-+    /* skb sanity check */
-+    if (!skb->len || (skb->len > MRVDRV_MAXIMUM_ETH_PACKET_SIZE)) {
-+        PRINTM(ERROR, "Tx Error: Bad skb length %d : %d\n", skb->len,
-+               MRVDRV_MAXIMUM_ETH_PACKET_SIZE);
-+        priv->stats.tx_dropped++;
-+        kfree(skb);
-+        goto done;
-+    }
-+    skb_queue_tail(&priv->adapter->tx_queue, skb);
-+    wake_up_interruptible(&priv->MainThread.waitQ);
-+    if (skb_queue_len(&priv->adapter->tx_queue) > TX_HIGH_WATERMARK) {
-+        UpdateTransStart(dev);
-+        os_stop_queue(priv);
-+    }
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief ioctl function - entry point
-+ *
-+ *  @param dev      A pointer to net_device structure
-+ *  @param req      A pointer to ifreq structure
-+ *  @param cmd      command
-+ *  @return         UAP_STATUS_SUCCESS--success, otherwise fail
-+ */
-+static int
-+uap_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+
-+    ENTER();
-+
-+    PRINTM(CMND, "uap_do_ioctl: ioctl cmd = 0x%x\n", cmd);
-+
-+    switch (cmd) {
-+    case UAPHOSTCMD:
-+        ret = uap_hostcmd_ioctl(dev, req);
-+        break;
-+    case UAP_POWER_MODE:
-+        ret = uap_power_mode_ioctl(dev, req);
-+        break;
-+    default:
-+        ret = -EINVAL;
-+        break;
-+    }
-+
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function handles events generated by firmware
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @param payload A pointer to payload buffer
-+ *  @param len           Length of the payload
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+int
-+uap_process_event(uap_private * priv, u8 * payload, uint len)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    uap_adapter *Adapter = priv->adapter;
-+    struct sk_buff *skb = NULL;
-+    struct nlmsghdr *nlh = NULL;
-+    struct sock *sk = Adapter->nl_sk;
-+    AP_Event *pEvent;
-+
-+    ENTER();
-+    Adapter->ps_state = PS_STATE_AWAKE;
-+    if (len > NL_MAX_PAYLOAD) {
-+        PRINTM(ERROR, "event size is too big!!! len=%d\n", len);
-+        ret = UAP_STATUS_FAILURE;
-+        goto done;
-+    }
-+    pEvent = (AP_Event *) payload;
-+    PRINTM(CMND, "Event: %d\n", pEvent->EventId);
-+    switch (pEvent->EventId) {
-+    case MICRO_AP_EV_ID_BSS_START:
-+        memcpy(priv->uap_dev.netdev->dev_addr, pEvent->MacAddr, ETH_ALEN);
-+        DBG_HEXDUMP(CMD_D, "BSS MAC addr", priv->uap_dev.netdev->dev_addr,
-+                    ETH_ALEN);
-+        break;
-+    case MICRO_AP_EV_BSS_ACTIVE:
-+        // carrier on
-+        priv->MediaConnected = TRUE;
-+        os_carrier_on(priv);
-+        os_start_queue(priv);
-+        break;
-+    case MICRO_AP_EV_BSS_IDLE:
-+        os_stop_queue(priv);
-+        os_carrier_off(priv);
-+        priv->MediaConnected = FALSE;
-+        break;
-+    case EVENT_PS_AWAKE:
-+        PRINTM(CMND, "UAP: PS_AWAKE\n");
-+        Adapter->ps_state = PS_STATE_AWAKE;
-+        Adapter->WakeupTries = 0;
-+        break;
-+    case EVENT_PS_SLEEP:
-+        PRINTM(CMND, "UAP: PS_SLEEP\n");
-+        Adapter->ps_state = PS_STATE_PRE_SLEEP;
-+        break;
-+    default:
-+        break;
-+    }
-+    if ((pEvent->EventId == EVENT_PS_AWAKE) ||
-+        (pEvent->EventId == EVENT_PS_SLEEP))
-+        goto done;
-+    if (sk) {
-+        /* Allocate skb */
-+        if (!(skb = alloc_skb(NLMSG_SPACE(NL_MAX_PAYLOAD), GFP_ATOMIC))) {
-+            PRINTM(ERROR, "Could not allocate skb for netlink.\n");
-+            ret = UAP_STATUS_FAILURE;
-+            goto done;
-+        }
-+        nlh = (struct nlmsghdr *) skb->data;
-+        nlh->nlmsg_len = NLMSG_SPACE(len);
-+
-+        /* From kernel */
-+        nlh->nlmsg_pid = 0;
-+        nlh->nlmsg_flags = 0;
-+
-+        /* Data */
-+        skb_put(skb, nlh->nlmsg_len);
-+        memcpy(NLMSG_DATA(nlh), payload, len);
-+
-+        /* From Kernel */
-+        NETLINK_CB(skb).pid = 0;
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-+        /* Multicast message */
-+        NETLINK_CB(skb).dst_pid = 0;
-+#endif
-+
-+        /* Multicast group number */
-+        NETLINK_CB(skb).dst_group = NL_MULTICAST_GROUP;
-+
-+        /* Send message */
-+        netlink_broadcast(sk, skb, 0, NL_MULTICAST_GROUP, GFP_KERNEL);
-+
-+        ret = UAP_STATUS_SUCCESS;
-+    } else {
-+        PRINTM(ERROR, "Could not send event through NETLINK. Link down.\n");
-+        ret = UAP_STATUS_FAILURE;
-+    }
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function handles the interrupt. it will change PS
-+ *  state if applicable. it will wake up main_thread to handle
-+ *  the interrupt event as well.
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return        n/a
-+ */
-+void
-+uap_interrupt(uap_private * priv)
-+{
-+    ENTER();
-+    priv->adapter->IntCounter++;
-+    priv->adapter->WakeupTries = 0;
-+    PRINTM(INFO, "*\n");
-+    wake_up_interruptible(&priv->MainThread.waitQ);
-+
-+    LEAVE();
-+
-+}
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
-+/** Network device handlers */
-+static const struct net_device_ops uap_netdev_ops = {
-+    .ndo_open = uap_open,
-+    .ndo_start_xmit = uap_hard_start_xmit,
-+    .ndo_stop = uap_close,
-+    .ndo_do_ioctl = uap_do_ioctl,
-+    .ndo_set_mac_address = uap_set_mac_address,
-+    .ndo_tx_timeout = uap_tx_timeout,
-+    .ndo_get_stats = uap_get_stats,
-+};
-+#endif
-+
-+/**
-+ * @brief This function adds the card. it will probe the
-+ * card, allocate the uap_priv and initialize the device.
-+ *
-+ *  @param card    A pointer to card
-+ *  @return        A pointer to uap_private structure
-+ */
-+uap_private *
-+uap_add_card(void *card)
-+{
-+    struct net_device *dev = NULL;
-+    uap_private *priv = NULL;
-+
-+    ENTER();
-+
-+    if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
-+        goto exit_sem_err;
-+
-+    /* Allocate an Ethernet device */
-+    if (!(dev = alloc_etherdev(sizeof(uap_private)))) {
-+        PRINTM(FATAL, "Init ethernet device failed!\n");
-+        goto error;
-+    }
-+    priv = (uap_private *) netdev_priv(dev);
-+
-+    /* Allocate name */
-+    if (dev_alloc_name(dev, "uap%d") < 0) {
-+        PRINTM(ERROR, "Could not allocate device name!\n");
-+        goto error;
-+    }
-+
-+    /* Allocate buffer for uap_adapter */
-+    if (!(priv->adapter = kmalloc(sizeof(uap_adapter), GFP_KERNEL))) {
-+        PRINTM(FATAL, "Allocate buffer for uap_adapter failed!\n");
-+        goto error;
-+    }
-+    memset(priv->adapter, 0, sizeof(uap_adapter));
-+
-+    priv->uap_dev.netdev = dev;
-+    priv->uap_dev.card = card;
-+    priv->MediaConnected = FALSE;
-+    uappriv = priv;
-+    ((struct sdio_mmc_card *) card)->priv = priv;
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-+    SET_MODULE_OWNER(dev);
-+#endif
-+
-+    /* Setup the OS Interface to our functions */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
-+    dev->open = uap_open;
-+    dev->stop = uap_close;
-+    dev->hard_start_xmit = uap_hard_start_xmit;
-+    dev->tx_timeout = uap_tx_timeout;
-+    dev->get_stats = uap_get_stats;
-+    dev->do_ioctl = uap_do_ioctl;
-+    dev->set_mac_address = uap_set_mac_address;
-+    dev->set_multicast_list = uap_set_multicast_list;
-+#else
-+    dev->netdev_ops = &uap_netdev_ops;
-+#endif
-+    dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT;
-+    dev->hard_header_len += sizeof(TxPD) + INTF_HEADER_LEN;
-+    dev->hard_header_len += HEADER_ALIGNMENT;
-+#define NETIF_F_DYNALLOC 16
-+    dev->features |= NETIF_F_DYNALLOC;
-+    dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
-+
-+    /* Init SW */
-+    if (uap_init_sw(priv)) {
-+        PRINTM(FATAL, "Software Init Failed\n");
-+        goto error;
-+    }
-+
-+    PRINTM(INFO, "Starting kthread...\n");
-+    priv->MainThread.priv = priv;
-+    spin_lock_init(&priv->driver_lock);
-+    uap_create_thread(uap_service_main_thread, &priv->MainThread,
-+                      "uap_main_service");
-+    while (priv->MainThread.pid == 0) {
-+        os_sched_timeout(2);
-+    }
-+
-+    /* Register the device */
-+    if (sbi_register_dev(priv) < 0) {
-+        PRINTM(FATAL, "Failed to register uap device!\n");
-+        goto err_registerdev;
-+    }
-+#ifdef FW_DNLD_NEEDED
-+    SET_NETDEV_DEV(dev, priv->hotplug_device);
-+#endif
-+
-+    /* Init FW and HW */
-+    if (uap_init_fw(priv)) {
-+        PRINTM(FATAL, "Firmware Init Failed\n");
-+        goto err_init_fw;
-+    }
-+
-+    priv->uap_dev.cmd_sent = FALSE;
-+    priv->uap_dev.data_sent = FALSE;
-+
-+    /* Get mac address from firmware */
-+    if (uap_get_mac_address(priv)) {
-+        PRINTM(FATAL, "Fail to get mac address\n");
-+        goto err_init_fw;
-+    }
-+    /* Register network device */
-+    if (register_netdev(dev)) {
-+        printk(KERN_ERR "Cannot register network device!\n");
-+        goto err_init_fw;
-+    }
-+#ifdef CONFIG_PROC_FS
-+    uap_proc_entry(priv, dev);
-+    uap_debug_entry(priv, dev);
-+#endif /* CPNFIG_PROC_FS */
-+    OS_REL_SEMAPHORE(&AddRemoveCardSem);
-+
-+    LEAVE();
-+    return priv;
-+  err_init_fw:
-+    sbi_unregister_dev(priv);
-+  err_registerdev:
-+    ((struct sdio_mmc_card *) card)->priv = NULL;
-+    /* Stop the thread servicing the interrupts */
-+    priv->adapter->SurpriseRemoved = TRUE;
-+    wake_up_interruptible(&priv->MainThread.waitQ);
-+    while (priv->MainThread.pid) {
-+        os_sched_timeout(1);
-+    }
-+  error:
-+    if (dev) {
-+        if (dev->reg_state == NETREG_REGISTERED)
-+            unregister_netdev(dev);
-+        if (priv->adapter)
-+            uap_free_adapter(priv);
-+        free_netdev(dev);
-+        uappriv = NULL;
-+    }
-+    OS_REL_SEMAPHORE(&AddRemoveCardSem);
-+  exit_sem_err:
-+    LEAVE();
-+    return NULL;
-+}
-+
-+/**
-+ *  @brief This function removes the card.
-+ *
-+ *  @param card    A pointer to card
-+ *  @return        UAP_STATUS_SUCCESS
-+ */
-+int
-+uap_remove_card(void *card)
-+{
-+    uap_private *priv = uappriv;
-+    uap_adapter *Adapter;
-+    struct net_device *dev;
-+
-+    ENTER();
-+
-+    if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
-+        goto exit_sem_err;
-+
-+    if (!priv || !(Adapter = priv->adapter)) {
-+        goto exit_remove;
-+    }
-+    Adapter->SurpriseRemoved = TRUE;
-+    if (Adapter->cmd_pending == TRUE) {
-+        /* Wake up cmd Q */
-+        Adapter->CmdWaitQWoken = TRUE;
-+        wake_up_interruptible(&Adapter->cmdwait_q);
-+    }
-+    dev = priv->uap_dev.netdev;
-+    if (priv->MediaConnected == TRUE) {
-+        os_stop_queue(priv);
-+        os_carrier_off(priv);
-+        priv->MediaConnected = FALSE;
-+    }
-+    Adapter->CmdSize = 0;
-+    Adapter->CmdWaitQWoken = TRUE;
-+    wake_up_interruptible(&Adapter->cmdwait_q);
-+    skb_queue_purge(&priv->adapter->tx_queue);
-+    skb_queue_purge(&priv->adapter->cmd_queue);
-+
-+    /* Disable interrupts on the card */
-+    sbi_disable_host_int(priv);
-+    PRINTM(INFO, "netdev_finish_unregister: %s%s.\n", dev->name,
-+           (dev->features & NETIF_F_DYNALLOC) ? "" : ", old style");
-+    unregister_netdev(dev);
-+    PRINTM(INFO, "Unregister finish\n");
-+    wake_up_interruptible(&priv->MainThread.waitQ);
-+    while (priv->MainThread.pid) {
-+        os_sched_timeout(1);
-+    }
-+
-+    if ((Adapter->nl_sk) && ((Adapter->nl_sk)->sk_socket)) {
-+        sock_release((Adapter->nl_sk)->sk_socket);
-+        Adapter->nl_sk = NULL;
-+    }
-+#ifdef CONFIG_PROC_FS
-+    uap_debug_remove(priv);
-+    uap_proc_remove(priv);
-+#endif
-+    sbi_unregister_dev(priv);
-+    PRINTM(INFO, "Free Adapter\n");
-+    uap_free_adapter(priv);
-+    priv->uap_dev.netdev = NULL;
-+    free_netdev(dev);
-+    uappriv = NULL;
-+
-+  exit_remove:
-+    OS_REL_SEMAPHORE(&AddRemoveCardSem);
-+  exit_sem_err:
-+    LEAVE();
-+    return UAP_STATUS_SUCCESS;
-+}
-+
-+/**
-+ *  @brief This function initializes module.
-+ *
-+ *  @return    UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+static int __init
-+uap_init_module(void)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    ENTER();
-+
-+    OS_INIT_SEMAPHORE(&AddRemoveCardSem);
-+    ret = sbi_register();
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function cleans module
-+ *
-+ *  @return        n/a
-+ */
-+static void __exit
-+uap_cleanup_module(void)
-+{
-+    ENTER();
-+
-+    if (OS_ACQ_SEMAPHORE_BLOCK(&AddRemoveCardSem))
-+        goto exit_sem_err;
-+
-+    if ((uappriv) && (uappriv->adapter)) {
-+        uap_func_shutdown(uappriv);
-+    }
-+    OS_REL_SEMAPHORE(&AddRemoveCardSem);
-+  exit_sem_err:
-+    sbi_unregister();
-+    LEAVE();
-+}
-+
-+module_init(uap_init_module);
-+module_exit(uap_cleanup_module);
-+module_param(helper_name, charp, 0);
-+MODULE_PARM_DESC(helper_name, "Helper name");
-+module_param(fw_name, charp, 0);
-+MODULE_PARM_DESC(fw_name, "Firmware name");
-+
-+MODULE_DESCRIPTION("M-UAP Driver");
-+MODULE_AUTHOR("Marvell International Ltd.");
-+MODULE_VERSION(DRIVER_VERSION);
-+MODULE_LICENSE("GPL");
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_proc.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_proc.c
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_proc.c    1970-01-01 01:00:00.000000000 +0100
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_proc.c        2012-07-31 14:23:04.000000000 +0200
-@@ -0,0 +1,296 @@
-+/** @file uap_proc.c
-+  * @brief This file contains functions for proc file.
-+  *
-+  * Copyright (C) 2008-2009, Marvell International Ltd.
-+  *
-+  * This software file (the "File") is distributed by Marvell International
-+  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
-+  * (the "License").  You may use, redistribute and/or modify this File in
-+  * accordance with the terms and conditions of the License, a copy of which
-+  * is available along with the File in the gpl.txt file or by writing to
-+  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+  * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-+  *
-+  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
-+  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
-+  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
-+  * this warranty disclaimer.
-+  *
-+  */
-+#ifdef CONFIG_PROC_FS
-+#include "uap_headers.h"
-+
-+/** /proc directory root */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-+#define PROC_DIR NULL
-+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+#define PROC_DIR &proc_root
-+#else
-+#define PROC_DIR proc_net
-+#endif
-+
-+/********************************************************
-+              Local Variables
-+********************************************************/
-+
-+/********************************************************
-+              Global Variables
-+********************************************************/
-+
-+/********************************************************
-+              Local Functions
-+********************************************************/
-+
-+/**
-+ *  @brief proc read function
-+ *
-+ *  @param page          pointer to buffer
-+ *  @param start   read data starting position
-+ *  @param offset  offset
-+ *  @param count   counter
-+ *  @param eof     end of file flag
-+ *  @param data    data to output
-+ *  @return      number of output data
-+ */
-+static int
-+uap_proc_read(char *page, char **start, off_t offset,
-+              int count, int *eof, void *data)
-+{
-+    int i;
-+    char *p = page;
-+    struct net_device *netdev = data;
-+    struct netdev_hw_addr *ha;
-+    char fmt[64];
-+    uap_private *priv = (uap_private *) netdev_priv(netdev);
-+
-+    if (offset != 0) {
-+        *eof = 1;
-+        goto exit;
-+    }
-+
-+    strcpy(fmt, DRIVER_VERSION);
-+
-+    p += sprintf(p, "driver_name = " "\"uap\"\n");
-+    p += sprintf(p, "driver_version = %s-(FP%s)", fmt, FPNUM);
-+    p += sprintf(p, "\nInterfaceName=\"%s\"\n", netdev->name);
-+    p += sprintf(p, "State=\"%s\"\n",
-+                 ((priv->MediaConnected ==
-+                   FALSE) ? "Disconnected" : "Connected"));
-+    p += sprintf(p, "MACAddress=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
-+                 netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
-+                 netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
-+    i = 0;
-+    netdev_for_each_mc_addr(ha, netdev) {
-+        ++i;
-+    }
-+    p += sprintf(p, "MCCount=\"%d\"\n", i);
-+
-+    /*
-+     * Put out the multicast list
-+     */
-+    i = 0;
-+    netdev_for_each_mc_addr(ha, netdev) {
-+        p += sprintf(p,
-+                     "MCAddr[%d]=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
-+                     i++,
-+                     ha->addr[0], ha->addr[1],
-+                     ha->addr[2], ha->addr[3],
-+                     ha->addr[4], ha->addr[5]);
-+    }
-+
-+    p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
-+    p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
-+    p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
-+    p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
-+    p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
-+    p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
-+    p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
-+    p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
-+    p += sprintf(p, "num_tx_timeout = %u\n", priv->num_tx_timeout);
-+    p += sprintf(p, "carrier %s\n",
-+                 ((netif_carrier_ok(priv->uap_dev.netdev)) ? "on" : "off"));
-+    p += sprintf(p, "tx queue %s\n",
-+                 ((netif_queue_stopped(priv->uap_dev.netdev)) ? "stopped" :
-+                  "started"));
-+
-+  exit:
-+    return (p - page);
-+}
-+
-+/**
-+ *  @brief hwstatus proc write function
-+ *
-+ *  @param f     file pointer
-+ *  @param buf     pointer to data buffer
-+ *  @param cnt     data number to write
-+ *  @param data    data to write
-+ *  @return      number of data
-+ */
-+static int
-+uap_hwstatus_write(struct file *f, const char *buf, unsigned long cnt,
-+                   void *data)
-+{
-+    struct net_device *netdev = data;
-+    uap_private *priv = (uap_private *) netdev_priv(netdev);
-+    char databuf[10];
-+    int hwstatus;
-+    MODULE_GET;
-+    if (cnt > 10) {
-+        MODULE_PUT;
-+        return cnt;
-+    }
-+    if (copy_from_user(databuf, buf, cnt)) {
-+        MODULE_PUT;
-+        return 0;
-+    }
-+    hwstatus = string_to_number(databuf);
-+    switch (hwstatus) {
-+    case HWReset:
-+        PRINTM(MSG, "reset hw\n");
-+        uap_soft_reset(priv);
-+        priv->adapter->HardwareStatus = HWReset;
-+        break;
-+    default:
-+        break;
-+    }
-+    MODULE_PUT;
-+    return cnt;
-+}
-+
-+/**
-+ *  @brief hwstatus proc read function
-+ *
-+ *  @param page          pointer to buffer
-+ *  @param s       read data starting position
-+ *  @param off     offset
-+ *  @param cnt     counter
-+ *  @param eof     end of file flag
-+ *  @param data    data to output
-+ *  @return      number of output data
-+ */
-+static int
-+uap_hwstatus_read(char *page, char **s, off_t off, int cnt, int *eof,
-+                  void *data)
-+{
-+    char *p = page;
-+    struct net_device *netdev = data;
-+    uap_private *priv = (uap_private *) netdev_priv(netdev);
-+    MODULE_GET;
-+    p += sprintf(p, "%d\n", priv->adapter->HardwareStatus);
-+    MODULE_PUT;
-+    return p - page;
-+}
-+
-+/********************************************************
-+              Global Functions
-+********************************************************/
-+/**
-+ *  @brief create uap proc file
-+ *
-+ *  @param priv          pointer uap_private
-+ *  @param dev     pointer net_device
-+ *  @return      N/A
-+ */
-+void
-+uap_proc_entry(uap_private * priv, struct net_device *dev)
-+{
-+    struct proc_dir_entry *r = PROC_DIR;
-+
-+    PRINTM(INFO, "Creating Proc Interface\n");
-+    /* Check if uap directory already exists */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
-+    for (r = r->subdir; r; r = r->next) {
-+        if (r->namelen && !strcmp("uap", r->name)) {
-+            /* Directory exists */
-+            PRINTM(WARN, "proc directory already exists!\n");
-+            priv->proc_uap = r;
-+            break;
-+        }
-+    }
-+#endif
-+    if (!priv->proc_uap) {
-+        priv->proc_uap = proc_mkdir("uap", PROC_DIR);
-+        if (!priv->proc_uap)
-+            return;
-+        else
-+            atomic_set(&priv->proc_uap->count, 1);
-+    } else {
-+        atomic_inc(&priv->proc_uap->count);
-+    }
-+    priv->proc_entry = proc_mkdir(dev->name, priv->proc_uap);
-+
-+    if (priv->proc_entry) {
-+        r = create_proc_read_entry("info", 0, priv->proc_entry, uap_proc_read,
-+                                   dev);
-+        r = create_proc_entry("hwstatus", 0644, priv->proc_entry);
-+        if (r) {
-+            r->data = dev;
-+            r->read_proc = uap_hwstatus_read;
-+            r->write_proc = uap_hwstatus_write;
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
-+            r->owner = THIS_MODULE;
-+#endif
-+        } else
-+            PRINTM(MSG, "Fail to create proc hwstatus\n");
-+    }
-+}
-+
-+/**
-+ *  @brief remove proc file
-+ *
-+ *  @param priv          pointer uap_private
-+ *  @return      N/A
-+ */
-+void
-+uap_proc_remove(uap_private * priv)
-+{
-+    if (priv->proc_uap) {
-+        if (priv->proc_entry) {
-+            remove_proc_entry("info", priv->proc_entry);
-+            remove_proc_entry("hwstatus", priv->proc_entry);
-+        }
-+        remove_proc_entry(priv->uap_dev.netdev->name, priv->proc_uap);
-+        atomic_dec(&priv->proc_uap->count);
-+        if (atomic_read(&(priv->proc_uap->count)) == 0)
-+            remove_proc_entry("uap", PROC_DIR);
-+    }
-+}
-+
-+/**
-+ *  @brief convert string to number
-+ *
-+ *  @param s     pointer to numbered string
-+ *  @return      converted number from string s
-+ */
-+int
-+string_to_number(char *s)
-+{
-+    int r = 0;
-+    int base = 0;
-+    int pn = 1;
-+
-+    if (strncmp(s, "-", 1) == 0) {
-+        pn = -1;
-+        s++;
-+    }
-+    if ((strncmp(s, "0x", 2) == 0) || (strncmp(s, "0X", 2) == 0)) {
-+        base = 16;
-+        s += 2;
-+    } else
-+        base = 10;
-+
-+    for (s = s; *s != 0; s++) {
-+        if ((*s >= '0') && (*s <= '9'))
-+            r = (r * base) + (*s - '0');
-+        else if ((*s >= 'A') && (*s <= 'F'))
-+            r = (r * base) + (*s - 'A' + 10);
-+        else if ((*s >= 'a') && (*s <= 'f'))
-+            r = (r * base) + (*s - 'a' + 10);
-+        else
-+            break;
-+    }
-+
-+    return (r * pn);
-+}
-+
-+#endif
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c        1970-01-01 01:00:00.000000000 +0100
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.c    2012-07-31 14:23:04.000000000 +0200
-@@ -0,0 +1,1428 @@
-+/** @file uap_sdio_mmc.c
-+ *  @brief This file contains SDIO IF (interface) module
-+ *  related functions.
-+ *
-+ * Copyright (C) 2007-2009, Marvell International Ltd.
-+ *
-+ * This software file (the "File") is distributed by Marvell International
-+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
-+ * (the "License").  You may use, redistribute and/or modify this File in
-+ * accordance with the terms and conditions of the License, a copy of which
-+ * is available along with the File in the gpl.txt file or by writing to
-+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-+ *
-+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
-+ * this warranty disclaimer.
-+ *
-+ */
-+/****************************************************
-+Change log:
-+****************************************************/
-+
-+#include      "uap_sdio_mmc.h"
-+
-+#include <linux/firmware.h>
-+
-+/** define SDIO block size */
-+/* We support up to 480-byte block size due to FW buffer limitation. */
-+#define SD_BLOCK_SIZE         256
-+
-+/** define allocated buffer size */
-+#define ALLOC_BUF_SIZE                (((MAX(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, \
-+                                      MRVDRV_SIZE_OF_CMD_BUFFER) + INTF_HEADER_LEN \
-+                                      + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE) * SD_BLOCK_SIZE)
-+
-+/** Max retry number of CMD53 write */
-+#define MAX_WRITE_IOMEM_RETRY 2
-+
-+/********************************************************
-+              Local Variables
-+********************************************************/
-+
-+/** SDIO Rx unit */
-+static u8 sdio_rx_unit = 0;
-+
-+/**Interrupt status */
-+static u8 sd_ireg = 0;
-+/********************************************************
-+              Global Variables
-+********************************************************/
-+extern u8 *helper_name;
-+extern u8 *fw_name;
-+/** Default helper name */
-+#define DEFAULT_HELPER_NAME "mrvl/helper_sd.bin"
-+/** Default firmware name */
-+#define DEFAULT_FW_NAME "mrvl/sd8688_ap.bin"
-+
-+/********************************************************
-+              Local Functions
-+********************************************************/
-+/**
-+ *  @brief This function reads the IO register.
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @param reg           register to be read
-+ *  @param dat           A pointer to variable that keeps returned value
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+static int
-+sbi_read_ioreg(uap_private * priv, u32 reg, u8 * dat)
-+{
-+    struct sdio_mmc_card *card;
-+    int ret = UAP_STATUS_FAILURE;
-+
-+    ENTER();
-+
-+    card = priv->uap_dev.card;
-+    if (!card || !card->func) {
-+        PRINTM(ERROR, "sbi_read_ioreg(): card or function is NULL!\n");
-+        goto done;
-+    }
-+
-+    *dat = sdio_readb(card->func, reg, &ret);
-+    if (ret) {
-+        PRINTM(ERROR, "sbi_read_ioreg(): sdio_readb failed! ret=%d\n", ret);
-+        goto done;
-+    }
-+
-+    PRINTM(INFO, "sbi_read_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv,
-+           card->func->num, reg, *dat);
-+
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function writes the IO register.
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @param reg           register to be written
-+ *  @param dat           the value to be written
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+static int
-+sbi_write_ioreg(uap_private * priv, u32 reg, u8 dat)
-+{
-+    struct sdio_mmc_card *card;
-+    int ret = UAP_STATUS_FAILURE;
-+
-+    ENTER();
-+
-+    card = priv->uap_dev.card;
-+    if (!card || !card->func) {
-+        PRINTM(ERROR, "sbi_write_ioreg(): card or function is NULL!\n");
-+        goto done;
-+    }
-+
-+    PRINTM(INFO, "sbi_write_ioreg() priv=%p func=%d reg=%#x dat=%#x\n", priv,
-+           card->func->num, reg, dat);
-+
-+    sdio_writeb(card->func, dat, reg, &ret);
-+    if (ret) {
-+        PRINTM(ERROR, "sbi_write_ioreg(): sdio_readb failed! ret=%d\n", ret);
-+        goto done;
-+    }
-+
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function get rx_unit value
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+static int
-+sd_get_rx_unit(uap_private * priv)
-+{
-+    int ret = UAP_STATUS_SUCCESS;
-+    u8 reg;
-+
-+    ENTER();
-+
-+    ret = sbi_read_ioreg(priv, CARD_RX_UNIT_REG, &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, &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, &reg);
-+    if (ret)
-+        goto release_irq;
-+    else
-+        priv->uap_dev.ioport |= reg;
-+
-+    ret = sbi_read_ioreg(priv, IO_PORT_1_REG, &reg);
-+    if (ret)
-+        goto release_irq;
-+    else
-+        priv->uap_dev.ioport |= (reg << 8);
-+
-+    ret = sbi_read_ioreg(priv, IO_PORT_2_REG, &reg);
-+    if (ret)
-+        goto release_irq;
-+    else
-+        priv->uap_dev.ioport |= (reg << 16);
-+
-+    PRINTM(INFO, "SDIO FUNC #%d IO port: 0x%x\n", func->num,
-+           priv->uap_dev.ioport);
-+
-+    ret = sdio_set_block_size(card->func, SD_BLOCK_SIZE);
-+    if (ret) {
-+        PRINTM(ERROR, "%s: cannot set SDIO block size\n", __FUNCTION__);
-+        ret = UAP_STATUS_FAILURE;
-+        goto release_irq;
-+    }
-+    priv->hotplug_device = &func->dev;
-+
-+    if (helper_name == NULL) {
-+        helper_name = DEFAULT_HELPER_NAME;
-+    }
-+    if (fw_name == NULL) {
-+        fw_name = DEFAULT_FW_NAME;
-+    }
-+    sdio_release_host(func);
-+
-+    sdio_set_drvdata(func, card);
-+
-+    ret = UAP_STATUS_SUCCESS;
-+    goto done;
-+
-+  release_irq:
-+    sdio_release_irq(func);
-+  disable_func:
-+    sdio_disable_func(func);
-+  release_host:
-+    sdio_release_host(func);
-+
-+  done:
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function sends data to the card.
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @param payload A pointer to the data/cmd buffer
-+ *  @param nb    the length of data/cmd
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+int
-+sbi_host_to_card(uap_private * priv, u8 * payload, u16 nb)
-+{
-+    struct sdio_mmc_card *card = priv->uap_dev.card;
-+    int ret = UAP_STATUS_SUCCESS;
-+    int buf_block_len;
-+    int blksz;
-+    int i = 0;
-+    u8 *buf = NULL;
-+#ifdef PXA3XX_DMA_ALIGN
-+    void *tmpbuf = NULL;
-+    int tmpbufsz;
-+#endif
-+
-+    ENTER();
-+
-+    if (!card || !card->func) {
-+        PRINTM(ERROR, "card or function is NULL!\n");
-+        LEAVE();
-+        return UAP_STATUS_FAILURE;
-+    }
-+    buf = payload;
-+#ifdef PXA3XX_DMA_ALIGN
-+    if ((u32) payload & (PXA3XX_DMA_ALIGNMENT - 1)) {
-+        tmpbufsz = ALIGN_SZ(nb, PXA3XX_DMA_ALIGNMENT);
-+        tmpbuf = kmalloc(tmpbufsz, GFP_KERNEL);
-+        memset(tmpbuf, 0, tmpbufsz);
-+        /* Ensure 8-byte aligned CMD buffer */
-+        buf = (u8 *) ALIGN_ADDR(tmpbuf, PXA3XX_DMA_ALIGNMENT);
-+        memcpy(buf, payload, nb);
-+    }
-+#endif
-+    /* Allocate buffer and copy payload */
-+    blksz = SD_BLOCK_SIZE;
-+    buf_block_len = (nb + blksz - 1) / blksz;
-+    sdio_claim_host(card->func);
-+#define MAX_WRITE_IOMEM_RETRY 2
-+    priv->uap_dev.cmd_sent = TRUE;
-+    priv->uap_dev.data_sent = TRUE;
-+    do {
-+        /* Transfer data to card */
-+        ret = sdio_writesb(card->func, priv->uap_dev.ioport, buf,
-+                           buf_block_len * blksz);
-+        if (ret < 0) {
-+            i++;
-+            PRINTM(ERROR, "host_to_card, write iomem (%d) failed: %d\n", i,
-+                   ret);
-+            ret = UAP_STATUS_FAILURE;
-+            if (i > MAX_WRITE_IOMEM_RETRY)
-+                goto exit;
-+        } else {
-+            HEXDUMP("SDIO Blk Wr", payload, nb);
-+        }
-+    } while (ret == UAP_STATUS_FAILURE);
-+  exit:
-+    sdio_release_host(card->func);
-+#ifdef PXA3XX_DMA_ALIGN
-+    if (tmpbuf)
-+        kfree(tmpbuf);
-+#endif
-+    if (ret == UAP_STATUS_FAILURE) {
-+        priv->uap_dev.cmd_sent = FALSE;
-+        priv->uap_dev.data_sent = FALSE;
-+    }
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function reads CIS information.
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @param cisinfo A pointer to CIS information output buffer
-+ *  @param cislen  A pointer to length of CIS info output buffer
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+#if 0
-+static int
-+sbi_get_cis_info(uap_private * priv, void *cisinfo, int *cislen)
-+{
-+#define CIS_PTR (0x8000)
-+    struct sdio_mmc_card *card = priv->uap_dev.card;
-+    unsigned int i, cis_ptr = CIS_PTR;
-+    int ret = UAP_STATUS_FAILURE;
-+
-+    ENTER();
-+
-+    if (!card || !card->func) {
-+        PRINTM(ERROR, "sbi_get_cis_info(): card or function is NULL!\n");
-+        goto exit;
-+    }
-+#define MAX_SDIO_CIS_INFO_LEN (256)
-+    if (!cisinfo || (*cislen < MAX_SDIO_CIS_INFO_LEN)) {
-+        PRINTM(WARN, "ERROR! get_cis_info: insufficient buffer passed\n");
-+        goto exit;
-+    }
-+
-+    *cislen = MAX_SDIO_CIS_INFO_LEN;
-+
-+    sdio_claim_host(card->func);
-+
-+    PRINTM(INFO, "cis_ptr=%#x\n", cis_ptr);
-+
-+    /* Read the Tuple Data */
-+    for (i = 0; i < *cislen; i++) {
-+        ((unsigned char *) cisinfo)[i] =
-+            sdio_readb(card->func, cis_ptr + i, &ret);
-+        if (ret) {
-+            PRINTM(WARN, "get_cis_info error: ret=%d\n", ret);
-+            ret = UAP_STATUS_FAILURE;
-+            goto done;
-+        }
-+        PRINTM(INFO, "cisinfo[%d]=%#x\n", i, ((unsigned char *) cisinfo)[i]);
-+    }
-+
-+  done:
-+    sdio_release_host(card->func);
-+  exit:
-+    LEAVE();
-+    return ret;
-+}
-+#endif
-+/**
-+ *  @brief This function downloads helper image to the card.
-+ *
-+ *  @param priv       A pointer to uap_private structure
-+ *  @return           UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+int
-+sbi_prog_helper(uap_private * priv)
-+{
-+    struct sdio_mmc_card *card = priv->uap_dev.card;
-+    u8 *helper = NULL;
-+    int helperlen;
-+    int ret = UAP_STATUS_SUCCESS;
-+    void *tmphlprbuf = NULL;
-+    int tmphlprbufsz;
-+    u8 *hlprbuf;
-+    int hlprblknow;
-+    u32 tx_len;
-+#ifdef FW_DOWNLOAD_SPEED
-+    u32 tv1, tv2;
-+#endif
-+
-+    ENTER();
-+
-+    if (!card || !card->func) {
-+        PRINTM(ERROR, "sbi_prog_helper(): card or function is NULL!\n");
-+        goto done;
-+    }
-+
-+    if (priv->fw_helper) {
-+        helper = (u8 *) priv->fw_helper->data;
-+        helperlen = priv->fw_helper->size;
-+    } else {
-+        PRINTM(MSG, "No helper image found! Terminating download.\n");
-+        LEAVE();
-+        return UAP_STATUS_FAILURE;
-+    }
-+
-+    PRINTM(INFO, "Downloading helper image (%d bytes), block size %d bytes\n",
-+           helperlen, SD_BLOCK_SIZE);
-+
-+#ifdef FW_DOWNLOAD_SPEED
-+    tv1 = get_utimeofday();
-+#endif
-+
-+#ifdef PXA3XX_DMA_ALIGN
-+    tmphlprbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT);
-+#else /* !PXA3XX_DMA_ALIGN */
-+    tmphlprbufsz = UAP_UPLD_SIZE;
-+#endif /* !PXA3XX_DMA_ALIGN */
-+    tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL);
-+    if (!tmphlprbuf) {
-+        PRINTM(ERROR,
-+               "Unable to allocate buffer for helper. Terminating download\n");
-+        ret = UAP_STATUS_FAILURE;
-+        goto done;
-+    }
-+    memset(tmphlprbuf, 0, tmphlprbufsz);
-+#ifdef PXA3XX_DMA_ALIGN
-+    hlprbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, PXA3XX_DMA_ALIGNMENT);
-+#else /* !PXA3XX_DMA_ALIGN */
-+    hlprbuf = (u8 *) tmphlprbuf;
-+#endif /* !PXA3XX_DMA_ALIGN */
-+
-+    sdio_claim_host(card->func);
-+
-+    /* Perform helper data transfer */
-+    tx_len = (FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE) - INTF_HEADER_LEN;
-+    hlprblknow = 0;
-+    do {
-+        /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */
-+        ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY);
-+        if (ret < 0) {
-+            PRINTM(FATAL, "Helper download poll status timeout @ %d\n",
-+                   hlprblknow);
-+            goto done;
-+        }
-+
-+        /* More data? */
-+        if (hlprblknow >= helperlen)
-+            break;
-+
-+        /* Set blocksize to transfer - checking for last block */
-+        if (helperlen - hlprblknow < tx_len)
-+            tx_len = helperlen - hlprblknow;
-+
-+        /* Set length to the 4-byte header */
-+        *(u32 *) hlprbuf = uap_cpu_to_le32(tx_len);
-+
-+        /* Copy payload to buffer */
-+        memcpy(&hlprbuf[INTF_HEADER_LEN], &helper[hlprblknow], tx_len);
-+
-+        PRINTM(INFO, ".");
-+
-+        /* Send data */
-+        ret = sdio_writesb(card->func, priv->uap_dev.ioport,
-+                           hlprbuf, FIRMWARE_TRANSFER_NBLOCK * SD_BLOCK_SIZE);
-+
-+        if (ret < 0) {
-+            PRINTM(FATAL, "IO error during helper download @ %d\n", hlprblknow);
-+            goto done;
-+        }
-+
-+        hlprblknow += tx_len;
-+    } while (TRUE);
-+
-+#ifdef FW_DOWNLOAD_SPEED
-+    tv2 = get_utimeofday();
-+    PRINTM(INFO, "helper: %ld.%03ld.%03ld ", tv1 / 1000000,
-+           (tv1 % 1000000) / 1000, tv1 % 1000);
-+    PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000, (tv2 % 1000000) / 1000,
-+           tv2 % 1000);
-+    tv2 -= tv1;
-+    PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000, (tv2 % 1000000) / 1000,
-+           tv2 % 1000);
-+#endif
-+
-+    /* Write last EOF data */
-+    PRINTM(INFO, "\nTransferring helper image EOF block\n");
-+    memset(hlprbuf, 0x0, SD_BLOCK_SIZE);
-+    ret = sdio_writesb(card->func, priv->uap_dev.ioport,
-+                       hlprbuf, SD_BLOCK_SIZE);
-+
-+    if (ret < 0) {
-+        PRINTM(FATAL, "IO error in writing helper image EOF block\n");
-+        goto done;
-+    }
-+
-+    ret = UAP_STATUS_SUCCESS;
-+
-+  done:
-+    sdio_release_host(card->func);
-+    if (tmphlprbuf)
-+        kfree(tmphlprbuf);
-+
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function downloads firmware image to the card.
-+ *
-+ *  @param priv       A pointer to uap_private structure
-+ *  @return           UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+int
-+sbi_prog_fw_w_helper(uap_private * priv)
-+{
-+    struct sdio_mmc_card *card = priv->uap_dev.card;
-+    u8 *firmware = NULL;
-+    int firmwarelen;
-+    u8 base0;
-+    u8 base1;
-+    int ret = UAP_STATUS_SUCCESS;
-+    int offset;
-+    void *tmpfwbuf = NULL;
-+    int tmpfwbufsz;
-+    u8 *fwbuf;
-+    u16 len;
-+    int txlen = 0;
-+    int tx_blocks = 0;
-+    int i = 0;
-+    int tries = 0;
-+#ifdef FW_DOWNLOAD_SPEED
-+    u32 tv1, tv2;
-+#endif
-+
-+    ENTER();
-+
-+    if (!card || !card->func) {
-+        PRINTM(ERROR, "sbi_prog_fw_w_helper(): card or function is NULL!\n");
-+        goto done;
-+    }
-+
-+    if (priv->firmware) {
-+        firmware = (u8 *) priv->firmware->data;
-+        firmwarelen = priv->firmware->size;
-+    } else {
-+        PRINTM(MSG, "No firmware image found! Terminating download.\n");
-+        LEAVE();
-+        return UAP_STATUS_FAILURE;
-+    }
-+
-+    PRINTM(INFO, "Downloading FW image (%d bytes)\n", firmwarelen);
-+
-+#ifdef FW_DOWNLOAD_SPEED
-+    tv1 = get_utimeofday();
-+#endif
-+
-+#ifdef PXA3XX_DMA_ALIGN
-+    tmpfwbufsz = ALIGN_SZ(UAP_UPLD_SIZE, PXA3XX_DMA_ALIGNMENT);
-+#else /* PXA3XX_DMA_ALIGN */
-+    tmpfwbufsz = UAP_UPLD_SIZE;
-+#endif /* PXA3XX_DMA_ALIGN */
-+    tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL);
-+    if (!tmpfwbuf) {
-+        PRINTM(ERROR,
-+               "Unable to allocate buffer for firmware. Terminating download.\n");
-+        ret = UAP_STATUS_FAILURE;
-+        goto done;
-+    }
-+    memset(tmpfwbuf, 0, tmpfwbufsz);
-+#ifdef PXA3XX_DMA_ALIGN
-+    /* Ensure 8-byte aligned firmware buffer */
-+    fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, PXA3XX_DMA_ALIGNMENT);
-+#else /* PXA3XX_DMA_ALIGN */
-+    fwbuf = (u8 *) tmpfwbuf;
-+#endif /* PXA3XX_DMA_ALIGN */
-+
-+    sdio_claim_host(card->func);
-+
-+    /* Perform firmware data transfer */
-+    offset = 0;
-+    do {
-+        /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY bits */
-+        ret = mv_sdio_poll_card_status(priv, CARD_IO_READY | DN_LD_CARD_RDY);
-+        if (ret < 0) {
-+            PRINTM(FATAL, "FW download with helper poll status timeout @ %d\n",
-+                   offset);
-+            goto done;
-+        }
-+
-+        /* More data? */
-+        if (offset >= firmwarelen)
-+            break;
-+
-+        for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
-+            if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_0, &base0)) < 0) {
-+                PRINTM(WARN, "Dev BASE0 register read failed:"
-+                       " base0=0x%04X(%d). Terminating download.\n", base0,
-+                       base0);
-+                ret = UAP_STATUS_FAILURE;
-+                goto done;
-+            }
-+            if ((ret = sbi_read_ioreg(priv, HOST_F1_RD_BASE_1, &base1)) < 0) {
-+                PRINTM(WARN, "Dev BASE1 register read failed:"
-+                       " base1=0x%04X(%d). Terminating download.\n", base1,
-+                       base1);
-+                ret = UAP_STATUS_FAILURE;
-+                goto done;
-+            }
-+            len = (((u16) base1) << 8) | base0;
-+
-+            /* For SD8688 wait until the length is not 0, 1 or 2 before
-+               downloading the first FW block, since BOOT code writes the
-+               register to indicate the helper/FW download winner, the value
-+               could be 1 or 2 (Func1 or Func2). */
-+            if ((len && offset) || (len > 2))
-+                break;
-+            udelay(10);
-+        }
-+
-+        if (len == 0)
-+            break;
-+        else if (len > UAP_UPLD_SIZE) {
-+            PRINTM(FATAL, "FW download failure @ %d, invalid length %d\n",
-+                   offset, len);
-+            ret = UAP_STATUS_FAILURE;
-+            goto done;
-+        }
-+
-+        txlen = len;
-+
-+        if (len & BIT(0)) {
-+            i++;
-+            if (i > MAX_WRITE_IOMEM_RETRY) {
-+                PRINTM(FATAL,
-+                       "FW download failure @ %d, over max retry count\n",
-+                       offset);
-+                ret = UAP_STATUS_FAILURE;
-+                goto done;
-+            }
-+            PRINTM(ERROR, "FW CRC error indicated by the helper:"
-+                   " len = 0x%04X, txlen = %d\n", len, txlen);
-+            len &= ~BIT(0);
-+            /* Setting this to 0 to resend from same offset */
-+            txlen = 0;
-+        } else {
-+            i = 0;
-+
-+            /* Set blocksize to transfer - checking for last block */
-+            if (firmwarelen - offset < txlen) {
-+                txlen = firmwarelen - offset;
-+            }
-+            PRINTM(INFO, ".");
-+
-+            tx_blocks = (txlen + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE;
-+
-+            /* Copy payload to buffer */
-+            memcpy(fwbuf, &firmware[offset], txlen);
-+        }
-+
-+        /* Send data */
-+        ret = sdio_writesb(card->func, priv->uap_dev.ioport,
-+                           fwbuf, tx_blocks * SD_BLOCK_SIZE);
-+
-+        if (ret < 0) {
-+            PRINTM(ERROR, "FW download, write iomem (%d) failed @ %d\n", i,
-+                   offset);
-+            if (sbi_write_ioreg(priv, CONFIGURATION_REG, 0x04) < 0) {
-+                PRINTM(ERROR, "write ioreg failed (CFG)\n");
-+            }
-+        }
-+
-+        offset += txlen;
-+    } while (TRUE);
-+
-+    PRINTM(INFO, "\nFW download over, size %d bytes\n", offset);
-+
-+    ret = UAP_STATUS_SUCCESS;
-+  done:
-+#ifdef FW_DOWNLOAD_SPEED
-+    tv2 = get_utimeofday();
-+    PRINTM(INFO, "FW: %ld.%03ld.%03ld ", tv1 / 1000000,
-+           (tv1 % 1000000) / 1000, tv1 % 1000);
-+    PRINTM(INFO, " -> %ld.%03ld.%03ld ", tv2 / 1000000,
-+           (tv2 % 1000000) / 1000, tv2 % 1000);
-+    tv2 -= tv1;
-+    PRINTM(INFO, " == %ld.%03ld.%03ld\n", tv2 / 1000000,
-+           (tv2 % 1000000) / 1000, tv2 % 1000);
-+#endif
-+    sdio_release_host(card->func);
-+    if (tmpfwbuf)
-+        kfree(tmpfwbuf);
-+
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function checks if the firmware is ready to accept
-+ *  command or not.
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @param pollnum Poll number
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+int
-+sbi_check_fw_status(uap_private * priv, int pollnum)
-+{
-+    struct sdio_mmc_card *card = priv->uap_dev.card;
-+    int ret = UAP_STATUS_SUCCESS;
-+    u16 firmwarestat;
-+    int tries;
-+
-+    ENTER();
-+
-+    sdio_claim_host(card->func);
-+
-+    /* Wait for firmware initialization event */
-+    for (tries = 0; tries < pollnum; tries++) {
-+        if ((ret = sd_read_firmware_status(priv, &firmwarestat)) < 0)
-+            continue;
-+        if (firmwarestat == FIRMWARE_READY) {
-+            ret = UAP_STATUS_SUCCESS;
-+            break;
-+        } else {
-+            mdelay(10);
-+            ret = UAP_STATUS_FAILURE;
-+        }
-+    }
-+
-+    if (ret < 0)
-+        goto done;
-+
-+    ret = UAP_STATUS_SUCCESS;
-+    sd_get_rx_unit(priv);
-+
-+  done:
-+    sdio_release_host(card->func);
-+
-+    LEAVE();
-+    return ret;
-+}
-+
-+/**
-+ *  @brief This function set bus clock on/off
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @param option    TRUE--on , FALSE--off
-+ *  @return      UAP_STATUS_SUCCESS
-+ */
-+#if 0
-+static int
-+sbi_set_bus_clock(uap_private * priv, u8 option)
-+{
-+    ENTER();
-+    LEAVE();
-+    return UAP_STATUS_SUCCESS;
-+}
-+#endif
-+
-+/**
-+ *  @brief This function wakeup firmware
-+ *
-+ *  @param priv    A pointer to uap_private structure
-+ *  @return      UAP_STATUS_SUCCESS or UAP_STATUS_FAILURE
-+ */
-+int
-+sbi_wakeup_firmware(uap_private * priv)
-+{
-+    struct sdio_mmc_card *card = priv->uap_dev.card;
-+    int ret = UAP_STATUS_SUCCESS;
-+
-+    ENTER();
-+
-+    if (!card || !card->func) {
-+        PRINTM(ERROR, "card or function is NULL!\n");
-+        LEAVE();
-+        return UAP_STATUS_FAILURE;
-+    }
-+    sdio_claim_host(card->func);
-+    sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
-+    sdio_release_host(card->func);
-+    LEAVE();
-+    return ret;
-+}
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h        1970-01-01 01:00:00.000000000 +0100
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/libertas_uap/uap_sdio_mmc.h    2012-07-31 14:23:04.000000000 +0200
-@@ -0,0 +1,136 @@
-+/** @file uap_sdio_mmc.h
-+ *  @brief This file contains SDIO IF (interface) module
-+ *  related macros, enum, and structure.
-+ *
-+ * Copyright (C) 2007-2009, Marvell International Ltd.
-+ *
-+ * This software file (the "File") is distributed by Marvell International
-+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
-+ * (the "License").  You may use, redistribute and/or modify this File in
-+ * accordance with the terms and conditions of the License, a copy of which
-+ * is available along with the File in the gpl.txt file or by writing to
-+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
-+ *
-+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
-+ * this warranty disclaimer.
-+ *
-+ */
-+/****************************************************
-+Change log:
-+      10/10/07: initial version
-+****************************************************/
-+
-+#ifndef       _UAP_SDIO_MMC_H
-+#define       _UAP_SDIO_MMC_H
-+
-+#include      <linux/mmc/sdio.h>
-+#include      <linux/mmc/sdio_ids.h>
-+#include      <linux/mmc/sdio_func.h>
-+#include      <linux/mmc/card.h>
-+
-+#include      "uap_headers.h"
-+
-+/** The number of times to try when waiting for downloaded firmware to
-+     become active. (polling the scratch register). */
-+#define MAX_FIRMWARE_POLL_TRIES               100
-+
-+/** Firmware ready */
-+#define FIRMWARE_READY                        0xfedc
-+
-+/** Number of firmware blocks to transfer */
-+#define FIRMWARE_TRANSFER_NBLOCK      2
-+
-+/* Host Control Registers */
-+/** Host Control Registers : I/O port 0 */
-+#define IO_PORT_0_REG                 0x00
-+/** Host Control Registers : I/O port 1 */
-+#define IO_PORT_1_REG                 0x01
-+/** Host Control Registers : I/O port 2 */
-+#define IO_PORT_2_REG                 0x02
-+
-+/** Host Control Registers : Configuration */
-+#define CONFIGURATION_REG             0x03
-+/** Host Control Registers : Host without Command 53 finish host */
-+#define HOST_WO_CMD53_FINISH_HOST     (0x1U << 2)
-+/** Host Control Registers : Host power up */
-+#define HOST_POWER_UP                 (0x1U << 1)
-+/** Host Control Registers : Host power down */
-+#define HOST_POWER_DOWN                       (0x1U << 0)
-+
-+/** Host Control Registers : Host interrupt mask */
-+#define HOST_INT_MASK_REG             0x04
-+/** Host Control Registers : Upload host interrupt mask */
-+#define UP_LD_HOST_INT_MASK           (0x1U)
-+/** Host Control Registers : Download host interrupt mask */
-+#define DN_LD_HOST_INT_MASK           (0x2U)
-+/** Enable Host interrupt mask */
-+#define HIM_ENABLE                    (UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
-+/** Disable Host interrupt mask */
-+#define       HIM_DISABLE                     0xff
-+
-+/** Host Control Registers : Host interrupt status */
-+#define HOST_INTSTATUS_REG            0x05
-+/** Host Control Registers : Upload host interrupt status */
-+#define UP_LD_HOST_INT_STATUS         (0x1U)
-+/** Host Control Registers : Download host interrupt status */
-+#define DN_LD_HOST_INT_STATUS         (0x2U)
-+
-+/** Host F1 read base 0 */
-+#define HOST_F1_RD_BASE_0             0x10
-+/** Host F1 read base 1 */
-+#define HOST_F1_RD_BASE_1             0x11
-+
-+/** Card Control Registers : Card status register */
-+#define CARD_STATUS_REG               0x20
-+/** Card Control Registers : Card I/O ready */
-+#define CARD_IO_READY                 (0x1U << 3)
-+/** Card Control Registers : CIS card ready */
-+#define CIS_CARD_RDY                  (0x1U << 2)
-+/** Card Control Registers : Upload card ready */
-+#define UP_LD_CARD_RDY                (0x1U << 1)
-+/** Card Control Registers : Download card ready */
-+#define DN_LD_CARD_RDY                (0x1U << 0)
-+
-+/** Card Control Registers : Card OCR 0 register */
-+#define CARD_OCR_0_REG                0x34
-+/** Card Control Registers : Card OCR 1 register */
-+#define CARD_OCR_1_REG                0x35
-+
-+/** Firmware status 0 register */
-+#define CARD_FW_STATUS0_REG           0x40
-+/** Firmware status 1 register */
-+#define CARD_FW_STATUS1_REG           0x41
-+/** Rx length register */
-+#define CARD_RX_LEN_REG                       0x42
-+/** Rx unit register */
-+#define CARD_RX_UNIT_REG              0x43
-+
-+/** Chip Id Register 0 */
-+#define CARD_CHIP_ID_0_REG            0x801c
-+/** Chip Id Register 1 */
-+#define CARD_CHIP_ID_1_REG            0x801d
-+
-+#ifdef PXA3XX_DMA_ALIGN
-+/** DMA alignment value for PXA3XX platforms */
-+#define PXA3XX_DMA_ALIGNMENT    8
-+/** Macros for Data Alignment : size */
-+#define ALIGN_SZ(p, a)  \
-+    (((p) + ((a) - 1)) & ~((a) - 1))
-+
-+/** Macros for Data Alignment : address */
-+#define ALIGN_ADDR(p, a)    \
-+    ((((u32)(p)) + (((u32)(a)) - 1)) & ~(((u32)(a)) - 1))
-+#endif /* PXA3XX_DMA_ALIGN */
-+
-+struct sdio_mmc_card
-+{
-+        /** sdio_func structure pointer */
-+    struct sdio_func *func;
-+        /** uap_private structure pointer */
-+    uap_private *priv;
-+};
-+
-+#endif /* _UAP_SDIO_MMC_H */
-diff -Naur compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/Makefile compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/Makefile
---- compat-wireless-3.5-rc5-1-snpc.org/drivers/net/wireless/Makefile   2012-07-05 03:48:01.000000000 +0200
-+++ compat-wireless-3.5-rc5-1-snpc/drivers/net/wireless/Makefile       2012-07-31 14:20:01.343608619 +0200
-@@ -22,6 +22,8 @@
- obj-$(CONFIG_LIBERTAS_THINFIRM)       += libertas_tf/
-+obj-$(CONFIG_LIBERTAS_UAP)    += libertas_uap/
-+
- obj-$(CONFIG_ADM8211) += adm8211.o
- obj-$(CONFIG_MWL8K)   += mwl8k.o
diff --git a/src/patches/compat-wireless_codel-avoid-a-nul-rec_inv_sqrt.patch b/src/patches/compat-wireless_codel-avoid-a-nul-rec_inv_sqrt.patch
deleted file mode 100644 (file)
index 210a58c..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-From patchwork Mon Jul 30 06:52:21 2012
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: codel: refine one condition to avoid a nul rec_inv_sqrt
-Date: Sun, 29 Jul 2012 20:52:21 -0000
-From: Eric Dumazet <eric.dumazet@gmail.com>
-X-Patchwork-Id: 173968
-Message-Id: <1343631141.2626.13293.camel@edumazet-glaptop>
-To: David Miller <davem@davemloft.net>
-Cc: netdev <netdev@vger.kernel.org>, Anton Mich <lp2s1h@gmail.com>
-
-From: Eric Dumazet <edumazet@google.com>
-
-One condition before codel_Newton_step() was not good if
-we never left the dropping state for a flow. As a result
-rec_inv_sqrt was 0, instead of the ~0 initial value.
-
-codel control law was then set to a very aggressive mode, dropping
-many packets before reaching 'target' and recovering from this problem.
-
-To keep codel_vars_init() as efficient as possible, refine
-the condition to make sure rec_inv_sqrt initial value is correct
-
-Many thanks to Anton Mich for discovering the issue and suggesting
-a fix.
-
-Reported-by: Anton Mich <lp2s1h@gmail.com>
-Signed-off-by: Eric Dumazet <edumazet@google.com>
-
----
-include/net/codel.h |    8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
-
-
---
-To unsubscribe from this list: send the line "unsubscribe netdev" in
-the body of a message to majordomo@vger.kernel.org
-More majordomo info at  http://vger.kernel.org/majordomo-info.html
-
-diff --git a/include/net/codel.h b/include/net/codel.h
-index 550debf..389cf62 100644
---- a/include/net/codel.h
-+++ b/include/net/codel.h
-@@ -305,6 +305,8 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
-                       }
-               }
-       } else if (drop) {
-+              u32 delta;
-+
-               if (params->ecn && INET_ECN_set_ce(skb)) {
-                       stats->ecn_mark++;
-               } else {
-@@ -320,9 +322,11 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch,
-                * assume that the drop rate that controlled the queue on the
-                * last cycle is a good starting point to control it now.
-                */
--              if (codel_time_before(now - vars->drop_next,
-+              delta = vars->count - vars->lastcount;
-+              if (delta > 1 &&
-+                  codel_time_before(now - vars->drop_next,
-                                     16 * params->interval)) {
--                      vars->count = (vars->count - vars->lastcount) | 1;
-+                      vars->count = delta;
-                       /* we dont care if rec_inv_sqrt approximation
-                        * is not very precise :
-                        * Next Newton steps will correct it quadratically.
diff --git a/src/patches/dhcp-3.1_linux3.patch b/src/patches/dhcp-3.1_linux3.patch
deleted file mode 100644 (file)
index 44edb41..0000000
+++ /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 (file)
index 293c20c..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-commit 1ba025a9a21eda65d8c36cc0dbb51d214a3ebb1a
-Author: Daniel Jacobowitz <dan@codesourcery.com>
-Date:   Mon Jun 2 01:57:03 2008 +0000
-
-    2008-06-01  Paul Brook  <paul@codesourcery.com>
-           Zack Weinberg  <zack@codesourcery.com>
-           Daniel Jacobowitz  <dan@codesourcery.com>
-    
-       * sysdeps/arm/nptl/pthread_spin_lock.S,
-       sysdeps/arm/nptl/pthread_spin_trylock.S: Delete.
-       * sysdeps/arm/nptl/pthread_spin_lock.c,
-       sysdeps/arm/nptl/pthread_spin_trylock.c: New files using
-       atomic_compare_and_exchange_val_acq to take spinlocks.
-       * sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h (lll_trylock,
-       lll_cond_trylock): Use atomic_compare_and_exchange_val_acq.
-       (__lll_trylock, __lll_cond_trylock): Delete.
-       * sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h
-       (atomic_exchange_acq): Delete.
-       (atomic_full_barrier): Define.
-       (__arch_compare_and_exchange_val_32_acq): Use named operands.
-       * sysdeps/unix/sysv/linux/arm/eabi/configure.in: Update
-       arch_minimum_kernel to 2.6.16.
-       * sysdeps/unix/sysv/linux/arm/eabi/configure: Regenerated.
-
-diff --git a/sysdeps/arm/nptl/pthread_spin_lock.S b/sysdeps/arm/nptl/pthread_spin_lock.S
-deleted file mode 100644
-index bd6adf7..0000000
---- a/sysdeps/arm/nptl/pthread_spin_lock.S
-+++ /dev/null
-@@ -1,31 +0,0 @@
--/* Copyright (C) 2005 Free Software Foundation, Inc.
--   This file is part of the GNU C Library.
--
--   The GNU C Library is free software; you can redistribute it and/or
--   modify it under the terms of the GNU Lesser General Public
--   License as published by the Free Software Foundation; either
--   version 2.1 of the License, or (at your option) any later version.
--
--   The GNU C Library is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
--   Lesser General Public License for more details.
--
--   You should have received a copy of the GNU Lesser General Public
--   License along with the GNU C Library; if not, write to the Free
--   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
--   02111-1307 USA.  */
--
--#include <sysdep.h>
--
--      .text
--      .align  4
--
--ENTRY (pthread_spin_lock)
--      mov     r1, #1
--1:    swp     r2, r1, [r0]
--      teq     r2, #0
--      bne     1b
--      mov     r0, #0
--      PSEUDO_RET_NOERRNO
--END (pthread_spin_lock)
-diff --git a/sysdeps/arm/nptl/pthread_spin_lock.c b/sysdeps/arm/nptl/pthread_spin_lock.c
-new file mode 100644
-index 0000000..1217b89
---- /dev/null
-+++ b/sysdeps/arm/nptl/pthread_spin_lock.c
-@@ -0,0 +1,30 @@
-+/* Copyright (C) 2008 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, write to the Free
-+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+   02111-1307 USA.  */
-+
-+#include <atomic.h>
-+#include "pthreadP.h"
-+
-+int
-+pthread_spin_lock (pthread_spinlock_t *lock)
-+{
-+  while (atomic_compare_and_exchange_val_acq (lock, 1, 0) != 0)
-+   while (*lock != 0)
-+    ;
-+
-+  return 0;
-+}
-diff --git a/sysdeps/arm/nptl/pthread_spin_trylock.S b/sysdeps/arm/nptl/pthread_spin_trylock.S
-deleted file mode 100644
-index 8593150..0000000
---- a/sysdeps/arm/nptl/pthread_spin_trylock.S
-+++ /dev/null
-@@ -1,34 +0,0 @@
--/* Copyright (C) 2005 Free Software Foundation, Inc.
--   This file is part of the GNU C Library.
--
--   The GNU C Library is free software; you can redistribute it and/or
--   modify it under the terms of the GNU Lesser General Public
--   License as published by the Free Software Foundation; either
--   version 2.1 of the License, or (at your option) any later version.
--
--   The GNU C Library is distributed in the hope that it will be useful,
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
--   Lesser General Public License for more details.
--
--   You should have received a copy of the GNU Lesser General Public
--   License along with the GNU C Library; if not, write to the Free
--   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
--   02111-1307 USA.  */
--
--#define _ERRNO_H 1
--#include <bits/errno.h>
--
--#include <sysdep.h>
--
--      .text
--      .align  4
--
--ENTRY (pthread_spin_trylock)
--      mov     r1, #1
--      swp     r2, r1, [r0]
--      teq     r2, #0
--      moveq   r0, #0
--      movne   r0, #EBUSY
--      PSEUDO_RET_NOERRNO
--END (pthread_spin_trylock)
-diff --git a/sysdeps/arm/nptl/pthread_spin_trylock.c b/sysdeps/arm/nptl/pthread_spin_trylock.c
-new file mode 100644
-index 0000000..fb998d2
---- /dev/null
-+++ b/sysdeps/arm/nptl/pthread_spin_trylock.c
-@@ -0,0 +1,27 @@
-+/* Copyright (C) 2008 Free Software Foundation, Inc.
-+   This file is part of the GNU C Library.
-+
-+   The GNU C Library is free software; you can redistribute it and/or
-+   modify it under the terms of the GNU Lesser General Public
-+   License as published by the Free Software Foundation; either
-+   version 2.1 of the License, or (at your option) any later version.
-+
-+   The GNU C Library is distributed in the hope that it will be useful,
-+   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+   Lesser General Public License for more details.
-+
-+   You should have received a copy of the GNU Lesser General Public
-+   License along with the GNU C Library; if not, write to the Free
-+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+   02111-1307 USA.  */
-+
-+#include <errno.h>
-+#include <atomic.h>
-+#include "pthreadP.h"
-+
-+int
-+pthread_spin_trylock (pthread_spinlock_t *lock)
-+{
-+  return atomic_compare_and_exchange_val_acq (lock, 1, 0) ? EBUSY : 0;
-+}
-diff --git a/sysdeps/unix/sysv/linux/arm/eabi/configure b/sysdeps/unix/sysv/linux/arm/eabi/configure
-index ab83048..28fb9ef 100644
---- a/sysdeps/unix/sysv/linux/arm/eabi/configure
-+++ b/sysdeps/unix/sysv/linux/arm/eabi/configure
-@@ -1,5 +1,5 @@
- # This file is generated from configure.in by Autoconf.  DO NOT EDIT!
-  # Local configure fragment for sysdeps/unix/sysv/linux/arm/eabi.
--arch_minimum_kernel=2.6.14
-+arch_minimum_kernel=2.6.16
- libc_cv_gcc_unwind_find_fde=no
-diff --git a/sysdeps/unix/sysv/linux/arm/eabi/configure.in b/sysdeps/unix/sysv/linux/arm/eabi/configure.in
-index 83aa8fc..d1fb7f4 100644
---- a/sysdeps/unix/sysv/linux/arm/eabi/configure.in
-+++ b/sysdeps/unix/sysv/linux/arm/eabi/configure.in
-@@ -1,5 +1,5 @@
- GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
- # Local configure fragment for sysdeps/unix/sysv/linux/arm/eabi.
--arch_minimum_kernel=2.6.14
-+arch_minimum_kernel=2.6.16
- libc_cv_gcc_unwind_find_fde=no
-diff --git a/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h b/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h
-index 71ed714..247ddd3 100644
---- a/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h
-+++ b/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h
-@@ -37,22 +37,12 @@ typedef uintmax_t uatomic_max_t;
- void __arm_link_error (void);
--#define atomic_exchange_acq(mem, newvalue)                                  \
--  ({ __typeof (*mem) result;                                                \
--     if (sizeof (*mem) == 1)                                                \
--       __asm__ __volatile__ ("swpb %0, %1, [%2]"                            \
--                           : "=&r,&r" (result)                              \
--                           : "r,0" (newvalue), "r,r" (mem) : "memory");     \
--     else if (sizeof (*mem) == 4)                                           \
--       __asm__ __volatile__ ("swp %0, %1, [%2]"                                     \
--                           : "=&r,&r" (result)                              \
--                           : "r,0" (newvalue), "r,r" (mem) : "memory");     \
--     else                                                                   \
--       {                                                                    \
--       result = 0;                                                          \
--       abort ();                                                            \
--       }                                                                    \
--     result; })
-+#define atomic_full_barrier() \
-+     __asm__ __volatile__                                                   \
-+           ("mov\tip, #0xffff0fff\n\t"                                      \
-+            "mov\tlr, pc\n\t"                                               \
-+            "add\tpc, ip, #(0xffff0fa0 - 0xffff0fff)"                       \
-+            : : : "ip", "lr", "cc", "memory");
- /* Atomic compare and exchange.  This sequence relies on the kernel to
-    provide a compare and exchange operation which is atomic on the
-@@ -76,18 +66,19 @@ void __arm_link_error (void);
-      register __typeof (oldval) a_tmp asm ("r3");                           \
-      register __typeof (oldval) a_oldval2 asm ("r4") = (oldval);            \
-      __asm__ __volatile__                                                   \
--           ("0:\tldr\t%1,[%3]\n\t"                                          \
--            "cmp\t%1, %4\n\t"                                               \
-+           ("0:\tldr\t%[tmp],[%[ptr]]\n\t"                                  \
-+            "cmp\t%[tmp], %[old2]\n\t"                                      \
-             "bne\t1f\n\t"                                                   \
--            "mov\t%0, %4\n\t"                                               \
--            "mov\t%1, #0xffff0fff\n\t"                                      \
-+            "mov\t%[old], %[old2]\n\t"                                      \
-+            "mov\t%[tmp], #0xffff0fff\n\t"                                  \
-             "mov\tlr, pc\n\t"                                               \
--            "add\tpc, %1, #(0xffff0fc0 - 0xffff0fff)\n\t"                   \
-+            "add\tpc, %[tmp], #(0xffff0fc0 - 0xffff0fff)\n\t"               \
-             "bcc\t0b\n\t"                                                   \
--            "mov\t%1, %4\n\t"                                               \
-+            "mov\t%[tmp], %[old2]\n\t"                                      \
-             "1:"                                                            \
--            : "=&r" (a_oldval), "=&r" (a_tmp)                               \
--            : "r" (a_newval), "r" (a_ptr), "r" (a_oldval2)                  \
-+            : [old] "=&r" (a_oldval), [tmp] "=&r" (a_tmp)                   \
-+            : [new] "r" (a_newval), [ptr] "r" (a_ptr),                      \
-+              [old2] "r" (a_oldval2)                                        \
-             : "ip", "lr", "cc", "memory");                                  \
-      a_tmp; })
-diff --git a/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h b/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h
-index f48e867..889f97c 100644
---- a/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h
-+++ b/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h
-@@ -126,43 +126,11 @@
-   })
--static inline int __attribute__((always_inline))
--__lll_mutex_trylock (int *futex)
--{
--  int flag = 1, old;
--  asm volatile (
--    "\tswp    %[old], %[flag], [%[futex]]     @ try to take the lock\n"
--    "\tcmp    %[old], #1                      @ check old lock value\n"
--    "\tmovlo  %[flag], #0                     @ if we got it, return 0\n"
--    "\tswphi  %[flag], %[old], [%[futex]]     @ if it was contested,\n"
--    "                                         @ restore the contested flag,\n"
--    "                                         @ and check whether that won."
--    : [futex] "+&r" (futex), [flag] "+&r" (flag), [old] "=&r" (old)
--    : : "memory" );
--
--  return flag;
--}
--#define lll_mutex_trylock(lock)       __lll_mutex_trylock (&(lock))
--
--
--static inline int __attribute__((always_inline))
--__lll_mutex_cond_trylock (int *futex)
--{
--  int flag = 2, old;
--  asm volatile (
--    "\tswp    %[old], %[flag], [%[futex]]     @ try to take the lock\n"
--    "\tcmp    %[old], #1                      @ check old lock value\n"
--    "\tmovlo  %[flag], #0                     @ if we got it, return 0\n"
--    "\tswphi  %[flag], %[old], [%[futex]]     @ if it was contested,\n"
--    "                                         @ restore the contested flag,\n"
--    "                                         @ and check whether that won."
--    : [futex] "+&r" (futex), [flag] "+&r" (flag), [old] "=&r" (old)
--    : : "memory" );
--
--  return flag;
--}
--#define lll_mutex_cond_trylock(lock)  __lll_mutex_cond_trylock (&(lock))
-+#define lll_mutex_trylock(lock)       \
-+  atomic_compare_and_exchange_val_acq(&(lock), 1, 0)
-+#define lll_mutex_cond_trylock(lock)  \
-+  atomic_compare_and_exchange_val_acq(&(lock), 2, 0)
- #define __lll_robust_trylock(futex, id) \
-   (atomic_compare_and_exchange_val_acq (futex, id, 0) != 0)
diff --git a/src/patches/grub-gentoo-14.patch b/src/patches/grub-gentoo-14.patch
deleted file mode 100644 (file)
index d2bb959..0000000
+++ /dev/null
@@ -1,16087 +0,0 @@
-diff -Nur grub-0.97/acinclude.m4 grub-0.97-patched/acinclude.m4
---- grub-0.97/acinclude.m4     2004-04-27 22:48:06.000000000 +0200
-+++ grub-0.97-patched/acinclude.m4     2012-11-11 17:07:12.710729053 +0100
-@@ -57,7 +57,7 @@
- fi
- grub_cv_prog_objcopy_absolute=yes
- for link_addr in 2000 8000 7C00; do
--  if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
-+  if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} ${LDFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
-   else
-     AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
-   fi
-diff -Nur grub-0.97/ChangeLog grub-0.97-patched/ChangeLog
---- grub-0.97/ChangeLog        2005-05-08 04:47:02.000000000 +0200
-+++ grub-0.97-patched/ChangeLog        2012-11-11 17:07:12.708728989 +0100
-@@ -1,3 +1,127 @@
-+2008-05-20  Robert Millan  <rmh@aybabtu.com>
-+
-+      * netboot/cs89x0.c: Fix license violation.
-+      * netboot/cs89x0.h: Likewise.
-+
-+2008-04-10  Pavel Roskin  <proski@gnu.org>
-+
-+      * configure.ac: Always use "_cv_" in cache variables for
-+      compatibility with Autoconf 2.62.
-+
-+2008-03-28  Robert Millan  <rmh@aybabtu.com>
-+
-+      Surpass 1 TiB disk addressing limit.  Note: there are no plans to handle
-+      the 2 TiB disk limit in GRUB Legacy, since that would need considerable
-+      rework.  If you have >2TiB disks, use GRUB 2 instead.
-+
-+      * grub/asmstub.c (biosdisk): Add unsigned qualifier to `sector'.
-+      * stage2/bios.c (biosdisk): Likewise.
-+      * stage2/disk_io.c (rawread, devread, rawwrite, devwrite): Likewise.
-+      * stage2/shared.h (rawread, devread, rawwrite, devwrite): Likewise.
-+      * lib/device.c (get_drive_geometry): Replace BLKGETSIZE with
-+      BLKGETSIZE64.
-+
-+2007-10-29  Pavel Roskin  <proski@gnu.org>
-+
-+      * configure.ac: Test if '--build-id=none' is supported by the
-+      linker and add it to LDFLAGS if possible.  Build ID causes
-+      objcopy to generate huge binary files.
-+      * aclocal.m4 (grub_PROG_OBJCOPY_ABSOLUTE): Use LDFLAGS when
-+      linking, so that build ID doesn't break the test.
-+      * stage1/Makefile.am: Preserve LDFLAGS, use stage1_exec_LDFLAGS.
-+
-+2007-02-22  Pavel Roskin  <proski@gnu.org>
-+
-+      * stage2/iso9660.h: Remove unnecessary packed attributes.
-+
-+2007-02-22  Robert Millan  <rmh@aybabtu.com>
-+
-+      * util/mkbimage: Update my email address, and remove my name from
-+      some places where unnecessary credit is given.
-+
-+2006-09-10  Pavel Roskin  <proski@gnu.org>
-+
-+      * netboot/natsemi.c: Fix compile error with gcc 4.1.1.  Cast
-+      cannot make a variable volatile - it should be declared as such.
-+      * netboot/sis900.c: Likewise.
-+
-+2006-09-08  Pavel Roskin  <proski@gnu.org>
-+
-+      * netboot/etherboot.h: Remove incorrect extern declarations of
-+      the variables later declared static.  Move BOOTP_DATA_ADDR ...
-+      * netboot/main.c: ... here.  Eliminate end_of_rfc1533 - it's
-+      write-only.
-+
-+2006-06-24  Yoshinori K. Okuji  <okuji@enbug.org>
-+
-+      * docs/grub.texi: Changed the license term to the GNU Free
-+      Documentation License 1.2.
-+
-+      * docs/multiboot.texi: Reformatted to show the license term
-+      and the version number explicitly.
-+      
-+      * docs/fdl.texi: New file.
-+      
-+      * docs/Makefile.am (grub_TEXINFOS): Added fdl.texi.
-+
-+2006-06-24  Robert Millan  <robertmh@gnu.org>
-+
-+      * lib/device.c (write_to_partition): /dev/ataraid/ and /dev/rd/
-+      partitions have a "p" prefix.  Add it.
-+
-+2006-06-24  Robert Millan  <robertmh@gnu.org>
-+
-+      * lib/device.c (get_i2o_disk_name): New function.
-+      (init_device_map) [__linux__]: Add support for I2O devices.
-+
-+2006-05-02  Pavel Roskin  <proski@gnu.org>
-+
-+      * stage2/stage2.c (run_menu): Fix "savedefault" to save only top
-+      level menu positions.  Remember current position when calling a
-+      submenu.  Don't recalculate it when booting from a submenu.
-+
-+      * grub/main.c (main): Make sure the boot drive number doesn't
-+      exceed 255.
-+
-+2006-05-02  Vesa Jaaskelainen  <chaac@nic.fi>
-+
-+      * stage2/shared.h (vbe_mode): Back ported aligment fix from GRUB 2
-+      to GRUB Legacy.  Problem reported by Gerardo Richarte.
-+
-+2006-04-23  Robert Millan  <robertmh@gnu.org>
-+
-+      * grub/asmstub.c (get_diskinfo): Optimize sysctl routine.
-+
-+2006-04-20  Robert Millan  <robertmh@gnu.org>
-+
-+      Fixes for kernel of FreeBSD:
-+      * grub/asmstub.c (get_diskinfo): Toggle "kern.geom.debugflags" sysctl
-+      before opening a device for writing.
-+      * util/grub-install.in: Devices don't have this "r" prefix anymore.
-+
-+2006-04-16  Yoshinori K. Okuji  <okuji@enbug.org>
-+
-+      * docs/multiboot.texi: Correct the offset of address
-+      fields. Reported by Jeroen Dekkers.
-+
-+2006-03-21  Yoshinori K. Okuji  <okuji@enbug.org>
-+
-+      * stage2/builtins.c (setup_func): Specify the size of DEVICE to
-+      grub_strncat instead of a strange number 256. Reported by Vitaly
-+      Fertman <vitaly@namesys.com>.
-+
-+2005-09-29  Yoshinori K. Okuji  <okuji@enbug.org>
-+
-+      * docs/multiboot.texi: Fix a bug in the byte order of
-+      boot_device. I hope this won't affect any OS image.
-+      Increased the version number to 0.6.94.
-+
-+2005-09-28  Yoshinori K. Okuji  <okuji@enbug.org>
-+
-+      * stage2/boot.c (load_image): Even if an OS image is an ELF
-+      object, use the a.out kludge if MULTIBOOT_AOUT_KLUDGE is
-+      specified.
-+
- 2005-05-08  Yoshinori K. Okuji  <okuji@enbug.org>
-       * configure.ac (AC_INIT): Upgraded to 0.97.
-diff -Nur grub-0.97/configure.ac grub-0.97-patched/configure.ac
---- grub-0.97/configure.ac     2005-05-08 04:36:03.000000000 +0200
-+++ grub-0.97-patched/configure.ac     2012-11-11 17:07:12.752730394 +0100
-@@ -21,8 +21,12 @@
- AC_CANONICAL_HOST
- case "$host_cpu" in
--i[[3456]]86) host_cpu=i386 ;;
--x86_64) host_cpu=x86_64 ;;
-+i[[3456]]86)
-+  STAGE_MARCH="-march=$host_cpu"
-+  host_cpu=i386 ;;
-+x86_64)
-+  STAGE_MARCH="-march=i686"
-+  host_cpu=x86_64 ;;
- *) AC_MSG_ERROR([unsupported CPU type]) ;;
- esac
-@@ -56,12 +60,7 @@
- AC_CHECK_TOOL(CC, gcc)
- AC_PROG_CC
--# We need this for older versions of Autoconf.
--_AM_DEPENDENCIES(CC)
--
--dnl Because recent automake complains about AS, set it here.
--CCAS="$CC"
--AC_SUBST(CCAS)
-+AM_PROG_AS
- AC_ARG_WITH(binutils,
-   [  --with-binutils=DIR     search the directory DIR to find binutils])
-@@ -86,13 +85,13 @@
-     fi
-     STAGE1_CFLAGS="-O2"
-     GRUB_CFLAGS="-O2"
--    AC_CACHE_CHECK([whether optimization for size works], size_flag, [
-+    AC_CACHE_CHECK([whether optimization for size works], grub_cv_cc_Os, [
-       saved_CFLAGS=$CFLAGS
-       CFLAGS="-Os -g"
--      AC_TRY_COMPILE(, , size_flag=yes, size_flag=no)
-+      AC_TRY_COMPILE(, , grub_cv_cc_Os=yes, grub_cv_cc_Os=no)
-       CFLAGS=$saved_CFLAGS
-     ])
--    if test "x$size_flag" = xyes; then
-+    if test "x$grub_cv_cc_Os" = xyes; then
-       STAGE2_CFLAGS="-Os"
-     else
-       STAGE2_CFLAGS="-O2 -fno-strength-reduce -fno-unroll-loops"
-@@ -100,21 +99,38 @@
-     # OpenBSD has a GCC extension for protecting applications from
-     # stack smashing attacks, but GRUB doesn't want this feature.
-     AC_CACHE_CHECK([whether gcc has -fno-stack-protector],
--                 no_stack_protector_flag, [
-+                 grub_cv_cc_no_stack_protector, [
-       saved_CFLAGS=$CFLAGS
-       CFLAGS="-fno-stack-protector"
-       AC_TRY_COMPILE(,
-                    ,
--                   no_stack_protector_flag=yes,
--                   no_stack_protector_flag=no)
-+                   grub_cv_cc_no_stack_protector=yes,
-+                   grub_cv_cc_no_stack_protector=no)
-       CFLAGS=$saved_CFLAGS
-     ])
--    if test "x$no_stack_protector_flag" = xyes; then
-+    if test "x$grub_cv_cc_no_stack_protector" = xyes; then
-       STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-stack-protector"
-     fi
-+    # Position Independent Executables, but GRUB doesn't want this feature.
-+    AC_CACHE_CHECK([whether gcc has -fPIE on as default], grub_cv_cc_fpie, [
-+      AC_TRY_COMPILE(,[
-+              #if ! defined (__PIC__) || ! defined (__PIE__)
-+              #error
-+              #endif
-+              ],
-+            grub_cv_cc_fpie=yes,
-+            grub_cv_cc_fpie=no)
-+    ])
-+    if test "x$grub_cv_cc_fpie" = xyes; then
-+      STAGE1_CFLAGS="$STAGE1_CFLAGS -nopie"
-+      STAGE2_CFLAGS="$STAGE2_CFLAGS -nopie"
-+    fi
-   fi
- fi
-+STAGE1_CFLAGS="$STAGE1_CFLAGS -fno-strict-aliasing $STAGE_MARCH"
-+STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-strict-aliasing $STAGE_MARCH"
-+GRUB_CFLAGS="$GRUB_CFLAGS -fno-strict-aliasing"
- AC_SUBST(STAGE1_CFLAGS)
- AC_SUBST(STAGE2_CFLAGS)
- AC_SUBST(GRUB_CFLAGS)
-@@ -123,33 +139,44 @@
- CPPFLAGS="$CPPFLAGS -Wall -Wmissing-prototypes -Wunused -Wshadow"
- CPPFLAGS="$CPPFLAGS -Wpointer-arith"
--AC_CACHE_CHECK([whether -Wundef works], undef_flag, [
-+AC_CACHE_CHECK([whether -Wundef works], grub_cv_cc_Wundef, [
-   saved_CPPFLAGS="$CPPFLAGS"
-   CPPFLAGS="-Wundef"
--  AC_TRY_COMPILE(, , undef_flag=yes, undef_flag=no)
-+  AC_TRY_COMPILE(, , grub_cv_cc_Wundef=yes, grub_cv_cc_Wundef=no)
-   CPPFLAGS="$saved_CPPFLAGS"
- ])
- # The options `-falign-*' are supported by gcc 3.0 or later.
- # Probably it is sufficient to only check for -falign-loops.
--AC_CACHE_CHECK([whether -falign-loops works], [falign_loop_flag], [
-+AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [
-   saved_CPPFLAGS="$CPPFLAGS"
-   CPPFLAGS="-falign-loops=1"
--  AC_TRY_COMPILE(, , [falign_loop_flag=yes], [falign_loop_flag=no])
-+  AC_TRY_COMPILE(, , [grub_cv_cc_falign_loop=yes], [grub_cv_cc_falign_loop=no])
-   CPPFLAGS="$saved_CPPFLAGS"
- ])
- # Force no alignment to save space.
--if test "x$falign_loop_flag" = xyes; then
-+if test "x$grub_cv_cc_falign_loop" = xyes; then
-   CPPFLAGS="$CPPFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1"
- else
-   CPPFLAGS="$CPPFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
- fi
--if test "x$undef_flag" = xyes; then
-+if test "x$grub_cv_cc_Wundef" = xyes; then
-   CPPFLAGS="$CPPFLAGS -Wundef"
- fi
-+# Check if build ID can be disabled in the linker
-+AC_MSG_CHECKING([whether linker accepts `--build-id=none'])
-+save_LDFLAGS="$LDFLAGS"
-+LDFLAGS="$LDFLAGS -Wl,--build-id=none"
-+AC_TRY_LINK(, , build_id_flag=yes, build_id_flag=no)
-+AC_MSG_RESULT([$build_id_flag])
-+LDFLAGS="$save_LDFLAGS"
-+if test "x$build_id_flag" = xyes; then
-+  LDFLAGS="$LDFLAGS -Wl,--build-id=none"
-+fi
-+
- if test "x$with_binutils" != x; then
- dnl  AC_PATH_TOOL(OBJCOPY, objcopy, , "$with_binutils:$PATH")
-   AC_PATH_PROG(OBJCOPY, objcopy, , "$with_binutils:$PATH")
-@@ -595,6 +622,11 @@
-   [  --enable-diskless       enable diskless support])
- AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
-+dnl Graphical splashscreen support
-+AC_ARG_ENABLE(graphics,
-+  [  --disable-graphics      disable graphics terminal support])
-+AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
-+
- dnl Hercules terminal
- AC_ARG_ENABLE(hercules,
-   [  --disable-hercules      disable hercules terminal support])
-diff -Nur grub-0.97/docs/fdl.texi grub-0.97-patched/docs/fdl.texi
---- grub-0.97/docs/fdl.texi    1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/docs/fdl.texi    2012-11-11 17:07:12.712729117 +0100
-@@ -0,0 +1,452 @@
-+
-+@node GNU Free Documentation License
-+@appendixsec GNU Free Documentation License
-+
-+@cindex FDL, GNU Free Documentation License
-+@center Version 1.2, November 2002
-+
-+@display
-+Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
-+51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
-+
-+Everyone is permitted to copy and distribute verbatim copies
-+of this license document, but changing it is not allowed.
-+@end display
-+
-+@enumerate 0
-+@item
-+PREAMBLE
-+
-+The purpose of this License is to make a manual, textbook, or other
-+functional and useful document @dfn{free} in the sense of freedom: to
-+assure everyone the effective freedom to copy and redistribute it,
-+with or without modifying it, either commercially or noncommercially.
-+Secondarily, this License preserves for the author and publisher a way
-+to get credit for their work, while not being considered responsible
-+for modifications made by others.
-+
-+This License is a kind of ``copyleft'', which means that derivative
-+works of the document must themselves be free in the same sense.  It
-+complements the GNU General Public License, which is a copyleft
-+license designed for free software.
-+
-+We have designed this License in order to use it for manuals for free
-+software, because free software needs free documentation: a free
-+program should come with manuals providing the same freedoms that the
-+software does.  But this License is not limited to software manuals;
-+it can be used for any textual work, regardless of subject matter or
-+whether it is published as a printed book.  We recommend this License
-+principally for works whose purpose is instruction or reference.
-+
-+@item
-+APPLICABILITY AND DEFINITIONS
-+
-+This License applies to any manual or other work, in any medium, that
-+contains a notice placed by the copyright holder saying it can be
-+distributed under the terms of this License.  Such a notice grants a
-+world-wide, royalty-free license, unlimited in duration, to use that
-+work under the conditions stated herein.  The ``Document'', below,
-+refers to any such manual or work.  Any member of the public is a
-+licensee, and is addressed as ``you''.  You accept the license if you
-+copy, modify or distribute the work in a way requiring permission
-+under copyright law.
-+
-+A ``Modified Version'' of the Document means any work containing the
-+Document or a portion of it, either copied verbatim, or with
-+modifications and/or translated into another language.
-+
-+A ``Secondary Section'' is a named appendix or a front-matter section
-+of the Document that deals exclusively with the relationship of the
-+publishers or authors of the Document to the Document's overall
-+subject (or to related matters) and contains nothing that could fall
-+directly within that overall subject.  (Thus, if the Document is in
-+part a textbook of mathematics, a Secondary Section may not explain
-+any mathematics.)  The relationship could be a matter of historical
-+connection with the subject or with related matters, or of legal,
-+commercial, philosophical, ethical or political position regarding
-+them.
-+
-+The ``Invariant Sections'' are certain Secondary Sections whose titles
-+are designated, as being those of Invariant Sections, in the notice
-+that says that the Document is released under this License.  If a
-+section does not fit the above definition of Secondary then it is not
-+allowed to be designated as Invariant.  The Document may contain zero
-+Invariant Sections.  If the Document does not identify any Invariant
-+Sections then there are none.
-+
-+The ``Cover Texts'' are certain short passages of text that are listed,
-+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
-+the Document is released under this License.  A Front-Cover Text may
-+be at most 5 words, and a Back-Cover Text may be at most 25 words.
-+
-+A ``Transparent'' copy of the Document means a machine-readable copy,
-+represented in a format whose specification is available to the
-+general public, that is suitable for revising the document
-+straightforwardly with generic text editors or (for images composed of
-+pixels) generic paint programs or (for drawings) some widely available
-+drawing editor, and that is suitable for input to text formatters or
-+for automatic translation to a variety of formats suitable for input
-+to text formatters.  A copy made in an otherwise Transparent file
-+format whose markup, or absence of markup, has been arranged to thwart
-+or discourage subsequent modification by readers is not Transparent.
-+An image format is not Transparent if used for any substantial amount
-+of text.  A copy that is not ``Transparent'' is called ``Opaque''.
-+
-+Examples of suitable formats for Transparent copies include plain
-+@sc{ascii} without markup, Texinfo input format, La@TeX{} input
-+format, @acronym{SGML} or @acronym{XML} using a publicly available
-+@acronym{DTD}, and standard-conforming simple @acronym{HTML},
-+PostScript or @acronym{PDF} designed for human modification.  Examples
-+of transparent image formats include @acronym{PNG}, @acronym{XCF} and
-+@acronym{JPG}.  Opaque formats include proprietary formats that can be
-+read and edited only by proprietary word processors, @acronym{SGML} or
-+@acronym{XML} for which the @acronym{DTD} and/or processing tools are
-+not generally available, and the machine-generated @acronym{HTML},
-+PostScript or @acronym{PDF} produced by some word processors for
-+output purposes only.
-+
-+The ``Title Page'' means, for a printed book, the title page itself,
-+plus such following pages as are needed to hold, legibly, the material
-+this License requires to appear in the title page.  For works in
-+formats which do not have any title page as such, ``Title Page'' means
-+the text near the most prominent appearance of the work's title,
-+preceding the beginning of the body of the text.
-+
-+A section ``Entitled XYZ'' means a named subunit of the Document whose
-+title either is precisely XYZ or contains XYZ in parentheses following
-+text that translates XYZ in another language.  (Here XYZ stands for a
-+specific section name mentioned below, such as ``Acknowledgements'',
-+``Dedications'', ``Endorsements'', or ``History''.)  To ``Preserve the Title''
-+of such a section when you modify the Document means that it remains a
-+section ``Entitled XYZ'' according to this definition.
-+
-+The Document may include Warranty Disclaimers next to the notice which
-+states that this License applies to the Document.  These Warranty
-+Disclaimers are considered to be included by reference in this
-+License, but only as regards disclaiming warranties: any other
-+implication that these Warranty Disclaimers may have is void and has
-+no effect on the meaning of this License.
-+
-+@item
-+VERBATIM COPYING
-+
-+You may copy and distribute the Document in any medium, either
-+commercially or noncommercially, provided that this License, the
-+copyright notices, and the license notice saying this License applies
-+to the Document are reproduced in all copies, and that you add no other
-+conditions whatsoever to those of this License.  You may not use
-+technical measures to obstruct or control the reading or further
-+copying of the copies you make or distribute.  However, you may accept
-+compensation in exchange for copies.  If you distribute a large enough
-+number of copies you must also follow the conditions in section 3.
-+
-+You may also lend copies, under the same conditions stated above, and
-+you may publicly display copies.
-+
-+@item
-+COPYING IN QUANTITY
-+
-+If you publish printed copies (or copies in media that commonly have
-+printed covers) of the Document, numbering more than 100, and the
-+Document's license notice requires Cover Texts, you must enclose the
-+copies in covers that carry, clearly and legibly, all these Cover
-+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
-+the back cover.  Both covers must also clearly and legibly identify
-+you as the publisher of these copies.  The front cover must present
-+the full title with all words of the title equally prominent and
-+visible.  You may add other material on the covers in addition.
-+Copying with changes limited to the covers, as long as they preserve
-+the title of the Document and satisfy these conditions, can be treated
-+as verbatim copying in other respects.
-+
-+If the required texts for either cover are too voluminous to fit
-+legibly, you should put the first ones listed (as many as fit
-+reasonably) on the actual cover, and continue the rest onto adjacent
-+pages.
-+
-+If you publish or distribute Opaque copies of the Document numbering
-+more than 100, you must either include a machine-readable Transparent
-+copy along with each Opaque copy, or state in or with each Opaque copy
-+a computer-network location from which the general network-using
-+public has access to download using public-standard network protocols
-+a complete Transparent copy of the Document, free of added material.
-+If you use the latter option, you must take reasonably prudent steps,
-+when you begin distribution of Opaque copies in quantity, to ensure
-+that this Transparent copy will remain thus accessible at the stated
-+location until at least one year after the last time you distribute an
-+Opaque copy (directly or through your agents or retailers) of that
-+edition to the public.
-+
-+It is requested, but not required, that you contact the authors of the
-+Document well before redistributing any large number of copies, to give
-+them a chance to provide you with an updated version of the Document.
-+
-+@item
-+MODIFICATIONS
-+
-+You may copy and distribute a Modified Version of the Document under
-+the conditions of sections 2 and 3 above, provided that you release
-+the Modified Version under precisely this License, with the Modified
-+Version filling the role of the Document, thus licensing distribution
-+and modification of the Modified Version to whoever possesses a copy
-+of it.  In addition, you must do these things in the Modified Version:
-+
-+@enumerate A
-+@item
-+Use in the Title Page (and on the covers, if any) a title distinct
-+from that of the Document, and from those of previous versions
-+(which should, if there were any, be listed in the History section
-+of the Document).  You may use the same title as a previous version
-+if the original publisher of that version gives permission.
-+
-+@item
-+List on the Title Page, as authors, one or more persons or entities
-+responsible for authorship of the modifications in the Modified
-+Version, together with at least five of the principal authors of the
-+Document (all of its principal authors, if it has fewer than five),
-+unless they release you from this requirement.
-+
-+@item
-+State on the Title page the name of the publisher of the
-+Modified Version, as the publisher.
-+
-+@item
-+Preserve all the copyright notices of the Document.
-+
-+@item
-+Add an appropriate copyright notice for your modifications
-+adjacent to the other copyright notices.
-+
-+@item
-+Include, immediately after the copyright notices, a license notice
-+giving the public permission to use the Modified Version under the
-+terms of this License, in the form shown in the Addendum below.
-+
-+@item
-+Preserve in that license notice the full lists of Invariant Sections
-+and required Cover Texts given in the Document's license notice.
-+
-+@item
-+Include an unaltered copy of this License.
-+
-+@item
-+Preserve the section Entitled ``History'', Preserve its Title, and add
-+to it an item stating at least the title, year, new authors, and
-+publisher of the Modified Version as given on the Title Page.  If
-+there is no section Entitled ``History'' in the Document, create one
-+stating the title, year, authors, and publisher of the Document as
-+given on its Title Page, then add an item describing the Modified
-+Version as stated in the previous sentence.
-+
-+@item
-+Preserve the network location, if any, given in the Document for
-+public access to a Transparent copy of the Document, and likewise
-+the network locations given in the Document for previous versions
-+it was based on.  These may be placed in the ``History'' section.
-+You may omit a network location for a work that was published at
-+least four years before the Document itself, or if the original
-+publisher of the version it refers to gives permission.
-+
-+@item
-+For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
-+the Title of the section, and preserve in the section all the
-+substance and tone of each of the contributor acknowledgements and/or
-+dedications given therein.
-+
-+@item
-+Preserve all the Invariant Sections of the Document,
-+unaltered in their text and in their titles.  Section numbers
-+or the equivalent are not considered part of the section titles.
-+
-+@item
-+Delete any section Entitled ``Endorsements''.  Such a section
-+may not be included in the Modified Version.
-+
-+@item
-+Do not retitle any existing section to be Entitled ``Endorsements'' or
-+to conflict in title with any Invariant Section.
-+
-+@item
-+Preserve any Warranty Disclaimers.
-+@end enumerate
-+
-+If the Modified Version includes new front-matter sections or
-+appendices that qualify as Secondary Sections and contain no material
-+copied from the Document, you may at your option designate some or all
-+of these sections as invariant.  To do this, add their titles to the
-+list of Invariant Sections in the Modified Version's license notice.
-+These titles must be distinct from any other section titles.
-+
-+You may add a section Entitled ``Endorsements'', provided it contains
-+nothing but endorsements of your Modified Version by various
-+parties---for example, statements of peer review or that the text has
-+been approved by an organization as the authoritative definition of a
-+standard.
-+
-+You may add a passage of up to five words as a Front-Cover Text, and a
-+passage of up to 25 words as a Back-Cover Text, to the end of the list
-+of Cover Texts in the Modified Version.  Only one passage of
-+Front-Cover Text and one of Back-Cover Text may be added by (or
-+through arrangements made by) any one entity.  If the Document already
-+includes a cover text for the same cover, previously added by you or
-+by arrangement made by the same entity you are acting on behalf of,
-+you may not add another; but you may replace the old one, on explicit
-+permission from the previous publisher that added the old one.
-+
-+The author(s) and publisher(s) of the Document do not by this License
-+give permission to use their names for publicity for or to assert or
-+imply endorsement of any Modified Version.
-+
-+@item
-+COMBINING DOCUMENTS
-+
-+You may combine the Document with other documents released under this
-+License, under the terms defined in section 4 above for modified
-+versions, provided that you include in the combination all of the
-+Invariant Sections of all of the original documents, unmodified, and
-+list them all as Invariant Sections of your combined work in its
-+license notice, and that you preserve all their Warranty Disclaimers.
-+
-+The combined work need only contain one copy of this License, and
-+multiple identical Invariant Sections may be replaced with a single
-+copy.  If there are multiple Invariant Sections with the same name but
-+different contents, make the title of each such section unique by
-+adding at the end of it, in parentheses, the name of the original
-+author or publisher of that section if known, or else a unique number.
-+Make the same adjustment to the section titles in the list of
-+Invariant Sections in the license notice of the combined work.
-+
-+In the combination, you must combine any sections Entitled ``History''
-+in the various original documents, forming one section Entitled
-+``History''; likewise combine any sections Entitled ``Acknowledgements'',
-+and any sections Entitled ``Dedications''.  You must delete all
-+sections Entitled ``Endorsements.''
-+
-+@item
-+COLLECTIONS OF DOCUMENTS
-+
-+You may make a collection consisting of the Document and other documents
-+released under this License, and replace the individual copies of this
-+License in the various documents with a single copy that is included in
-+the collection, provided that you follow the rules of this License for
-+verbatim copying of each of the documents in all other respects.
-+
-+You may extract a single document from such a collection, and distribute
-+it individually under this License, provided you insert a copy of this
-+License into the extracted document, and follow this License in all
-+other respects regarding verbatim copying of that document.
-+
-+@item
-+AGGREGATION WITH INDEPENDENT WORKS
-+
-+A compilation of the Document or its derivatives with other separate
-+and independent documents or works, in or on a volume of a storage or
-+distribution medium, is called an ``aggregate'' if the copyright
-+resulting from the compilation is not used to limit the legal rights
-+of the compilation's users beyond what the individual works permit.
-+When the Document is included in an aggregate, this License does not
-+apply to the other works in the aggregate which are not themselves
-+derivative works of the Document.
-+
-+If the Cover Text requirement of section 3 is applicable to these
-+copies of the Document, then if the Document is less than one half of
-+the entire aggregate, the Document's Cover Texts may be placed on
-+covers that bracket the Document within the aggregate, or the
-+electronic equivalent of covers if the Document is in electronic form.
-+Otherwise they must appear on printed covers that bracket the whole
-+aggregate.
-+
-+@item
-+TRANSLATION
-+
-+Translation is considered a kind of modification, so you may
-+distribute translations of the Document under the terms of section 4.
-+Replacing Invariant Sections with translations requires special
-+permission from their copyright holders, but you may include
-+translations of some or all Invariant Sections in addition to the
-+original versions of these Invariant Sections.  You may include a
-+translation of this License, and all the license notices in the
-+Document, and any Warranty Disclaimers, provided that you also include
-+the original English version of this License and the original versions
-+of those notices and disclaimers.  In case of a disagreement between
-+the translation and the original version of this License or a notice
-+or disclaimer, the original version will prevail.
-+
-+If a section in the Document is Entitled ``Acknowledgements'',
-+``Dedications'', or ``History'', the requirement (section 4) to Preserve
-+its Title (section 1) will typically require changing the actual
-+title.
-+
-+@item
-+TERMINATION
-+
-+You may not copy, modify, sublicense, or distribute the Document except
-+as expressly provided for under this License.  Any other attempt to
-+copy, modify, sublicense or distribute the Document is void, and will
-+automatically terminate your rights under this License.  However,
-+parties who have received copies, or rights, from you under this
-+License will not have their licenses terminated so long as such
-+parties remain in full compliance.
-+
-+@item
-+FUTURE REVISIONS OF THIS LICENSE
-+
-+The Free Software Foundation may publish new, revised versions
-+of the GNU Free Documentation License from time to time.  Such new
-+versions will be similar in spirit to the present version, but may
-+differ in detail to address new problems or concerns.  See
-+@uref{http://www.gnu.org/copyleft/}.
-+
-+Each version of the License is given a distinguishing version number.
-+If the Document specifies that a particular numbered version of this
-+License ``or any later version'' applies to it, you have the option of
-+following the terms and conditions either of that specified version or
-+of any later version that has been published (not as a draft) by the
-+Free Software Foundation.  If the Document does not specify a version
-+number of this License, you may choose any version ever published (not
-+as a draft) by the Free Software Foundation.
-+@end enumerate
-+
-+@page
-+@appendixsubsec ADDENDUM: How to use this License for your documents
-+
-+To use this License in a document you have written, include a copy of
-+the License in the document and put the following copyright and
-+license notices just after the title page:
-+
-+@smallexample
-+@group
-+  Copyright (C)  @var{year}  @var{your name}.
-+  Permission is granted to copy, distribute and/or modify this document
-+  under the terms of the GNU Free Documentation License, Version 1.2
-+  or any later version published by the Free Software Foundation;
-+  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
-+  Texts.  A copy of the license is included in the section entitled ``GNU
-+  Free Documentation License''.
-+@end group
-+@end smallexample
-+
-+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-+replace the ``with...Texts.'' line with this:
-+
-+@smallexample
-+@group
-+    with the Invariant Sections being @var{list their titles}, with
-+    the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
-+    being @var{list}.
-+@end group
-+@end smallexample
-+
-+If you have Invariant Sections without Cover Texts, or some other
-+combination of the three, merge those two alternatives to suit the
-+situation.
-+
-+If your document contains nontrivial examples of program code, we
-+recommend releasing these examples in parallel under your choice of
-+free software license, such as the GNU General Public License,
-+to permit their use in free software.
-+
-+@c Local Variables:
-+@c ispell-local-pdict: "ispell-dict"
-+@c End:
-+
-diff -Nur grub-0.97/docs/grub.8 grub-0.97-patched/docs/grub.8
---- grub-0.97/docs/grub.8      2005-05-08 04:48:56.000000000 +0200
-+++ grub-0.97-patched/docs/grub.8      2012-11-11 17:07:12.715729211 +0100
-@@ -1,5 +1,5 @@
- .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
--.TH GRUB "8" "May 2005" "grub (GNU GRUB 0.97)" FSF
-+.TH GRUB "8" "June 2006" "grub (GNU GRUB 0.97)" FSF
- .SH NAME
- grub \- the grub shell
- .SH SYNOPSIS
-diff -Nur grub-0.97/docs/grub.8.additions grub-0.97-patched/docs/grub.8.additions
---- grub-0.97/docs/grub.8.additions    1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/docs/grub.8.additions    2012-11-11 17:07:12.702728798 +0100
-@@ -0,0 +1,3 @@
-+[SEE ALSO]
-+.BR update-grub (8),
-+.BR grub-install (8).
-diff -Nur grub-0.97/docs/grub-install.8 grub-0.97-patched/docs/grub-install.8
---- grub-0.97/docs/grub-install.8      2005-05-08 04:48:56.000000000 +0200
-+++ grub-0.97-patched/docs/grub-install.8      2012-11-11 17:07:12.713729149 +0100
-@@ -1,5 +1,5 @@
- .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
--.TH GRUB-INSTALL "8" "May 2005" "grub-install (GNU GRUB 0.97)" FSF
-+.TH GRUB-INSTALL "8" "June 2006" "grub-install (GNU GRUB 0.97)" FSF
- .SH NAME
- grub-install \- install GRUB on your drive
- .SH SYNOPSIS
-diff -Nur grub-0.97/docs/grub-install.8.additions grub-0.97-patched/docs/grub-install.8.additions
---- grub-0.97/docs/grub-install.8.additions    1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/docs/grub-install.8.additions    2012-11-11 17:07:12.703728829 +0100
-@@ -0,0 +1,3 @@
-+[SEE ALSO]
-+.BR grub (8),
-+.BR update-grub (8).
-diff -Nur grub-0.97/docs/grub-md5-crypt.8 grub-0.97-patched/docs/grub-md5-crypt.8
---- grub-0.97/docs/grub-md5-crypt.8    2005-05-08 04:48:56.000000000 +0200
-+++ grub-0.97-patched/docs/grub-md5-crypt.8    2012-11-11 17:07:12.713729149 +0100
-@@ -1,5 +1,5 @@
- .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
--.TH GRUB-MD5-CRYPT "8" "May 2005" "grub-md5-crypt (GNU GRUB )" FSF
-+.TH GRUB-MD5-CRYPT "8" "June 2006" "grub-md5-crypt (GNU GRUB )" FSF
- .SH NAME
- grub-md5-crypt \- Encrypt a password in MD5 format
- .SH SYNOPSIS
-diff -Nur grub-0.97/docs/grub-terminfo.8 grub-0.97-patched/docs/grub-terminfo.8
---- grub-0.97/docs/grub-terminfo.8     2005-05-08 04:48:56.000000000 +0200
-+++ grub-0.97-patched/docs/grub-terminfo.8     2012-11-11 17:07:12.714729180 +0100
-@@ -1,5 +1,5 @@
- .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
--.TH GRUB-TERMINFO "8" "May 2005" "grub-terminfo (GNU GRUB 0.97)" FSF
-+.TH GRUB-TERMINFO "8" "June 2006" "grub-terminfo (GNU GRUB 0.97)" FSF
- .SH NAME
- grub-terminfo \- Generate a terminfo command from a terminfo name
- .SH SYNOPSIS
-diff -Nur grub-0.97/docs/grub.texi grub-0.97-patched/docs/grub.texi
---- grub-0.97/docs/grub.texi   2005-05-08 04:59:59.000000000 +0200
-+++ grub-0.97-patched/docs/grub.texi   2012-11-11 17:07:12.717729276 +0100
-@@ -2,22 +2,41 @@
- @c -*-texinfo-*-
- @c %**start of header
- @setfilename grub.info
--@settitle GRUB Manual
--@c %**end of header
--
- @include version.texi
--
-+@settitle GNU GRUB Manual @value{VERSION}
- @c Unify all our little indices for now.
- @syncodeindex fn cp
- @syncodeindex vr cp
- @syncodeindex ky cp
- @syncodeindex pg cp
- @syncodeindex tp cp
-+@c %**end of header
- @footnotestyle separate
- @paragraphindent 3
- @finalout
-+@copying
-+This manual is for GNU GRUB (version @value{VERSION},
-+@value{UPDATED}).
-+
-+Copyright @copyright{} 1999,2000,2001,2002,2004,2006 Free Software Foundation, Inc.
-+
-+@quotation
-+Permission is granted to copy, distribute and/or modify this document
-+under the terms of the GNU Free Documentation License, Version 1.2 or
-+any later version published by the Free Software Foundation; with no
-+Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,''
-+and with the Back-Cover Texts as in (a) below.  A copy of the
-+license is included in the section entitled ``GNU Free Documentation
-+License.''
-+
-+(a) The FSF's Back-Cover Text is: ``You have freedom to copy and modify
-+this GNU Manual, like GNU software.  Copies published by the Free
-+Software Foundation raise funds for GNU development.''
-+@end quotation
-+@end copying
-+
- @dircategory Kernel
- @direntry
- * GRUB: (grub).                 The GRand Unified Bootloader
-@@ -34,53 +53,16 @@
- @setchapternewpage odd
--@ifinfo
--Copyright @copyright{} 1999,2000,2001,2002,2004 Free Software Foundation, Inc.
--
--Permission is granted to make and distribute verbatim copies of
--this manual provided the copyright notice and this permission notice
--are preserved on all copies.
--
--@ignore
--Permission is granted to process this file through TeX and print the
--results, provided the printed document carries a copying permission
--notice identical to this one except for the removal of this paragraph
--(this paragraph not being relevant to the printed manual).
--
--@end ignore
--
--Permission is granted to copy and distribute modified versions of this
--manual under the conditions for verbatim copying, provided also that
--the entire resulting derived work is distributed under the terms of a
--permission notice identical to this one.
--
--Permission is granted to copy and distribute translations of this manual
--into another language, under the above conditions for modified versions.
--@end ifinfo
--
- @titlepage
- @sp 10
--@title the GRUB manual
-+@title the GNU GRUB manual
- @subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
- @author Gordon Matzigkeit
- @author Yoshinori K. Okuji
- @c The following two commands start the copyright page.
- @page
- @vskip 0pt plus 1filll
--Copyright @copyright{} 1999,2000,2001,2002,2004 Free Software Foundation, Inc.
--
--Permission is granted to make and distribute verbatim copies of
--this manual provided the copyright notice and this permission notice
--are preserved on all copies.
--Permission is granted to copy and distribute modified versions of this
--manual under the conditions for verbatim copying, provided that the entire
--resulting derived work is distributed under the terms of a permission
--notice identical to this one.
--
--Permission is granted to copy and distribute translations of this manual
--into another language, under the above conditions for modified versions,
--except that this permission notice may be stated in a translation approved
--by Free Software Foundation.
-+@insertcopying
- @end titlepage
- @c Output the table of contents at the beginning.
-@@ -91,12 +73,14 @@
- @ifnottex
- @node Top
--@top GRUB manual
-+@top GNU GRUB manual
- This is the documentation of GNU GRUB, the GRand Unified Bootloader,
- a flexible and powerful boot loader program for @sc{pc}s.
- This edition documents version @value{VERSION}.
-+
-+@insertcopying
- @end ifnottex
- @menu
-@@ -124,6 +108,7 @@
- * Reporting bugs::              Where you should send a bug report
- * Future::                      Some future plans on GRUB
- * Internals::                   Hacking GRUB
-+* Copying This Manual::         Copying This Manual
- * Index::
- @end menu
-@@ -3965,6 +3950,16 @@
- @include internals.texi
-+@node Copying This Manual
-+@appendix Copying This Manual
-+
-+@menu
-+* GNU Free Documentation License::  License for copying this manual.
-+@end menu
-+
-+@include fdl.texi
-+
-+
- @node Index
- @unnumbered Index
-diff -Nur grub-0.97/docs/help2man grub-0.97-patched/docs/help2man
---- grub-0.97/docs/help2man    2003-07-09 13:45:36.000000000 +0200
-+++ grub-0.97-patched/docs/help2man    2012-11-11 17:07:12.701728766 +0100
-@@ -455,7 +455,9 @@
-     $include{$sect} .= <<EOT;
- The full documentation for
- .B $program
--is maintained as a Texinfo manual.  If the
-+is maintained as a Texinfo manual in the
-+.B grub-doc
-+package.  If the
- .B info
- and
- .B $program
-diff -Nur grub-0.97/docs/Makefile.am grub-0.97-patched/docs/Makefile.am
---- grub-0.97/docs/Makefile.am 2003-07-09 13:45:35.000000000 +0200
-+++ grub-0.97-patched/docs/Makefile.am 2012-11-11 17:07:12.711729085 +0100
-@@ -1,5 +1,5 @@
- info_TEXINFOS = grub.texi multiboot.texi
--grub_TEXINFOS = internals.texi
-+grub_TEXINFOS = internals.texi fdl.texi
- EXAMPLES = boot.S kernel.c multiboot.h
- multiboot_TEXINFOS = boot.S.texi kernel.c.texi multiboot.h.texi
- man_MANS = grub.8 mbchk.1 grub-install.8 grub-md5-crypt.8 grub-terminfo.8
-@@ -37,14 +37,14 @@
-       $(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
- if MAINTAINER_MODE
--$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN)
-+$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN) $(srcdir)/grub.8.additions
-       $(PERL) $(srcdir)/$(HELP2MAN) --name="the grub shell" \
--              --section=8 --output=$@ $<
-+              --section=8 --include=$@.additions --output=$@ $<
--$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN)
-+$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN)  $(srcdir)/grub-install.8.additions
-       chmod 755 $<
-       $(PERL) $(srcdir)/$(HELP2MAN) --name="install GRUB on your drive" \
--              --section=8 --output=$@ $<
-+              --section=8 --include=$@.additions --output=$@ $<
- $(srcdir)/mbchk.1: ../util/mbchk $(srcdir)/$(HELP2MAN)
-       $(PERL) $(srcdir)/$(HELP2MAN) \
-diff -Nur grub-0.97/docs/mbchk.1 grub-0.97-patched/docs/mbchk.1
---- grub-0.97/docs/mbchk.1     2005-05-08 04:48:56.000000000 +0200
-+++ grub-0.97-patched/docs/mbchk.1     2012-11-11 17:07:12.717729276 +0100
-@@ -1,5 +1,5 @@
- .\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
--.TH MBCHK "1" "May 2005" "mbchk (GNU GRUB 0.97)" FSF
-+.TH MBCHK "1" "June 2006" "mbchk (GNU GRUB 0.97)" FSF
- .SH NAME
- mbchk \- check the format of a Multiboot kernel
- .SH SYNOPSIS
-diff -Nur grub-0.97/docs/menu.lst grub-0.97-patched/docs/menu.lst
---- grub-0.97/docs/menu.lst    2004-05-11 14:11:17.000000000 +0200
-+++ grub-0.97-patched/docs/menu.lst    2012-11-11 17:07:07.225553829 +0100
-@@ -11,6 +11,9 @@
- # Fallback to the second entry.
- fallback 1
-+# Splash image to show behind grub.
-+splashimage=(hd0,0)/boot/grub/splash.xpm.gz
-+
- # For booting GNU/Hurd
- title  GNU/Hurd
- root   (hd0,0)
-@@ -23,6 +26,11 @@
- kernel /vmlinuz root=/dev/hdb1
- #initrd /initrd.img
-+# For booting Gentoo with the static rescue shell
-+title  Gentoo (rescue shell)
-+root (hd1,0)
-+kernel /vmlinuz root=/dev/hdb1 init=/bin/bb
-+
- # For booting GNU/kFreeBSD
- title  GNU/kFreeBSD
- root   (hd0,2,a)
-diff -Nur grub-0.97/docs/menu.lst.orig grub-0.97-patched/docs/menu.lst.orig
---- grub-0.97/docs/menu.lst.orig       1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/docs/menu.lst.orig       2004-05-11 14:11:17.000000000 +0200
-@@ -0,0 +1,82 @@
-+#
-+# Sample boot menu configuration file
-+#
-+
-+# Boot automatically after 30 secs.
-+timeout 30
-+
-+# By default, boot the first entry.
-+default 0
-+
-+# Fallback to the second entry.
-+fallback 1
-+
-+# For booting GNU/Hurd
-+title  GNU/Hurd
-+root   (hd0,0)
-+kernel /boot/gnumach.gz root=hd0s1
-+module /boot/serverboot.gz
-+
-+# For booting GNU/Linux
-+title  GNU/Linux
-+root (hd1,0)
-+kernel /vmlinuz root=/dev/hdb1
-+#initrd /initrd.img
-+
-+# For booting GNU/kFreeBSD
-+title  GNU/kFreeBSD
-+root   (hd0,2,a)
-+kernel /boot/loader.gz
-+
-+# For booting GNU/kNetBSD
-+title  GNU/kNetBSD
-+root   (hd0,2,a)
-+kernel --type=netbsd /boot/knetbsd.gz
-+
-+# For booting Mach (getting kernel from floppy)
-+title  Utah Mach4 multiboot
-+root   (hd0,2)
-+pause  Insert the diskette now\a!!
-+kernel (fd0)/boot/kernel root=hd0s3
-+module (fd0)/boot/bootstrap
-+
-+# For booting FreeBSD
-+title  FreeBSD
-+root   (hd0,2,a)
-+kernel /boot/loader
-+
-+# For booting NetBSD
-+title  NetBSD
-+root   (hd0,2,a)
-+kernel --type=netbsd /netbsd
-+
-+# For booting OpenBSD
-+title  OpenBSD
-+root   (hd0,2,a)
-+kernel --type=netbsd /bsd
-+
-+# For booting OS/2
-+title OS/2
-+root  (hd0,1)
-+makeactive
-+# chainload OS/2 bootloader from the first sector
-+chainloader +1
-+# This is similar to "chainload", but loads a specific file
-+#chainloader /boot/chain.os2
-+
-+# For booting Windows NT or Windows95
-+title Windows NT / Windows 95 boot menu
-+rootnoverify (hd0,0)
-+makeactive
-+chainloader  +1
-+# For loading DOS if Windows NT is installed
-+# chainload /bootsect.dos
-+
-+# For installing GRUB into the hard disk
-+title Install GRUB into the hard disk
-+root    (hd0,0)
-+setup   (hd0)
-+
-+# Change the colors.
-+title Change the colors
-+color light-green/brown blink-red/blue
-diff -Nur grub-0.97/docs/multiboot.texi grub-0.97-patched/docs/multiboot.texi
---- grub-0.97/docs/multiboot.texi      2003-07-09 13:45:36.000000000 +0200
-+++ grub-0.97-patched/docs/multiboot.texi      2012-11-11 17:07:12.718729309 +0100
-@@ -1,32 +1,28 @@
- \input texinfo @c -*-texinfo-*-
--@c -*-texinfo-*-
- @c %**start of header
- @setfilename multiboot.info
--@settitle Multiboot Specification
--@c %**end of header
--
-+@set VERSION 0.6.95
-+@settitle Multiboot Specification version @value{VERSION}
- @c Unify all our little indices for now.
- @syncodeindex fn cp
- @syncodeindex vr cp
- @syncodeindex ky cp
- @syncodeindex pg cp
- @syncodeindex tp cp
-+@c %**end of header
- @footnotestyle separate
- @paragraphindent 3
- @finalout
-+@copying
-+Copyright @copyright{} 1995,96 Bryan Ford <baford@@cs.utah.edu>
--@dircategory Kernel
--@direntry
--* Multiboot Specification: (multiboot).               Multiboot Specification.
--@end direntry
-+Copyright @copyright{} 1995,96 Erich Stefan Boleyn <erich@@uruk.org>
--@ifinfo
--Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
--Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
--Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-+Copyright @copyright{} 1999,2000,2001,2002,2005,2006 Free Software Foundation, Inc.
-+@quotation
- Permission is granted to make and distribute verbatim copies of
- this manual provided the copyright notice and this permission notice
- are preserved on all copies.
-@@ -36,7 +32,6 @@
- results, provided the printed document carries a copying permission
- notice identical to this one except for the removal of this paragraph
- (this paragraph not being relevant to the printed manual).
--
- @end ignore
- Permission is granted to copy and distribute modified versions of this
-@@ -45,31 +40,23 @@
- permission notice identical to this one.
- Permission is granted to copy and distribute translations of this manual
--into another language, under the above conditions for modified versions.
--@end ifinfo
-+into another language, under the above conditions for modified
-+versions.
-+@end quotation
-+@end copying
-+
-+@dircategory Kernel
-+@direntry
-+* Multiboot Specification: (multiboot).               Multiboot Specification.
-+@end direntry
- @titlepage
- @sp 10
--@title The Multiboot Specification
-+@title The Multiboot Specification version @value{VERSION}
- @author Yoshinori K. Okuji, Bryan Ford, Erich Stefan Boleyn, Kunihiro Ishiguro
- @page
--
- @vskip 0pt plus 1filll
--Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
--Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
--Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
--
--Permission is granted to make and distribute verbatim copies of
--this manual provided the copyright notice and this permission notice
--are preserved on all copies.
--
--Permission is granted to copy and distribute modified versions of this
--manual under the conditions for verbatim copying, provided also that
--the entire resulting derived work is distributed under the terms of a
--permission notice identical to this one.
--
--Permission is granted to copy and distribute translations of this manual
--into another language, under the above conditions for modified versions.
-+@insertcopying
- @end titlepage
- @finalout
-@@ -80,7 +67,9 @@
- @top Multiboot Specification
- This file documents Multiboot Specification, the proposal for the boot
--sequence standard. This edition documents version 0.6.93.
-+sequence standard. This edition documents version @value{VERSION}.
-+
-+@insertcopying
- @end ifnottex
- @menu
-@@ -426,7 +415,7 @@
- kernel.
- If bit 16 in the @samp{flags} word is set, then the fields at offsets
--8-24 in the Multiboot header are valid, and the boot loader should use
-+12-28 in the Multiboot header are valid, and the boot loader should use
- them instead of the fields in the actual executable header to calculate
- where to load the OS image. This information does not need to be
- provided if the kernel image is in @sc{elf} format, but it @emph{must}
-@@ -677,7 +666,7 @@
- @example
- @group
- +-------+-------+-------+-------+
--| drive | part1 | part2 | part3 |
-+| part3 | part2 | part1 | drive |
- +-------+-------+-------+-------+
- @end group
- @end example
-@@ -1197,6 +1186,17 @@
- @item
- The maintainer changes to the GNU GRUB maintainer team
- @email{bug-grub@@gnu.org}, from Bryan Ford and Erich Stefan Boleyn.
-+
-+@item
-+The byte order of the @samp{boot_device} in Multiboot information is
-+reversed. This was a mistake.
-+
-+@item
-+The offset of the address fields were wrong.
-+
-+@item
-+The format is adapted to a newer Texinfo, and the version number is
-+specified more explicitly in the title.
- @end itemize
- @item 0.6
-diff -Nur grub-0.97/grub/asmstub.c grub-0.97-patched/grub/asmstub.c
---- grub-0.97/grub/asmstub.c   2005-02-16 21:45:14.000000000 +0100
-+++ grub-0.97-patched/grub/asmstub.c   2012-11-11 17:07:12.719729342 +0100
-@@ -42,6 +42,7 @@
- #include <sys/time.h>
- #include <termios.h>
- #include <signal.h>
-+#include <sys/mman.h>
- #ifdef __linux__
- # include <sys/ioctl.h>               /* ioctl */
-@@ -55,6 +56,10 @@
- # endif /* ! BLKFLSBUF */
- #endif /* __linux__ */
-+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
-+# include <sys/sysctl.h>
-+#endif
-+
- /* We want to prevent any circularararity in our stubs, as well as
-    libc name clashes. */
- #define WITHOUT_LIBC_STUBS 1
-@@ -79,7 +84,7 @@
- struct apm_info apm_bios_info;
- /* Emulation requirements. */
--char *grub_scratch_mem = 0;
-+void *grub_scratch_mem = 0;
- struct geometry *disks = 0;
-@@ -103,14 +108,62 @@
- static unsigned int serial_speed;
- #endif /* SIMULATE_SLOWNESS_OF_SERIAL */
-+/* This allocates page-aligned storage of the specified size, which must be
-+ * a multiple of the page size as determined by calling sysconf(_SC_PAGESIZE)
-+ */
-+#ifdef __linux__
-+static void *
-+grub_mmap_alloc(size_t len)
-+{
-+  int mmap_flags = MAP_ANONYMOUS|MAP_PRIVATE;
-+
-+#ifdef MAP_32BIT
-+  mmap_flags |= MAP_32BIT;
-+#endif
-+  /* Mark the simulated stack executable, as GCC uses stack trampolines
-+   * to implement nested functions. */
-+  return mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC, mmap_flags, -1, 0);
-+}
-+#else /* !defined(__linux__) */
-+static void *
-+grub_mmap_alloc(size_t len)
-+{
-+  int fd = 0, offset = 0, ret = 0;
-+  void *pa = MAP_FAILED; 
-+  char template[] = "/tmp/grub_mmap_alloc_XXXXXX";
-+  int e;
-+
-+  fd = mkstemp(template);
-+  if (fd < 0)
-+    return pa;
-+
-+  unlink(template);
-+
-+  ret = ftruncate(fd, len);
-+  if (ret < 0)
-+    return pa;
-+
-+  /* Mark the simulated stack executable, as GCC uses stack trampolines
-+   * to implement nested functions. */
-+  pa = mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC,
-+                  MAP_PRIVATE, fd, offset);
-+
-+  e = errno;
-+  close(fd);
-+  errno = e;
-+  return pa;
-+}
-+#endif /* defined(__linux__) */
-+
- /* The main entry point into this mess. */
- int
- grub_stage2 (void)
- {
-   /* These need to be static, because they survive our stack transitions. */
-   static int status = 0;
--  static char *realstack;
--  char *scratch, *simstack;
-+  static void *realstack;
-+  void *simstack_alloc_base, *simstack;
-+  size_t simstack_size, page_size;
-   int i;
-   auto void doit (void);
-@@ -142,9 +195,35 @@
-     }
-   assert (grub_scratch_mem == 0);
--  scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
--  assert (scratch);
--  grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4);
-+
-+  /* Allocate enough pages for 0x100000 + EXTENDED_SIZE + 15, and
-+   * make sure the memory is aligned to a multiple of the system's
-+   * page size */
-+  page_size = sysconf (_SC_PAGESIZE);
-+  simstack_size = ( 0x100000 + EXTENDED_MEMSIZE + 15);
-+  if (simstack_size % page_size)
-+    {
-+      /* If we're not on a page_size boundary, round up to the next one */
-+      simstack_size &= ~(page_size-1);
-+      simstack_size += page_size;
-+    }
-+
-+  /* Add one for a PROT_NONE boundary page at each end. */
-+  simstack_size += 2 * page_size;
-+
-+  simstack_alloc_base = grub_mmap_alloc(simstack_size);
-+  assert (simstack_alloc_base != MAP_FAILED);
-+
-+  /* mark pages above and below our simstack area as innaccessable.
-+   * If the implementation we're using doesn't support that, then the
-+   * new protection modes are undefined.  It's safe to just ignore
-+   * them, though.  It'd be nice if we knew that we'd get a SEGV for
-+   * touching the area, but that's all.  it'd be nice to have. */
-+  mprotect (simstack_alloc_base, page_size, PROT_NONE);
-+  mprotect ((void *)((unsigned long)simstack_alloc_base +
-+                         simstack_size - page_size),  page_size, PROT_NONE);
-+
-+  grub_scratch_mem = (void *)((unsigned long)simstack_alloc_base + page_size);
-   /* FIXME: simulate the memory holes using mprot, if available. */
-@@ -217,7 +296,7 @@
-   device_map = 0;
-   free (disks);
-   disks = 0;
--  free (scratch);
-+  munmap(simstack_alloc_base, simstack_size);
-   grub_scratch_mem = 0;
-   if (serial_device)
-@@ -777,7 +856,39 @@
-       /* Open read/write, or read-only if that failed. */
-       if (! read_only)
--      disks[drive].flags = open (devname, O_RDWR);
-+      {
-+/* By default, kernel of FreeBSD does not allow overwriting MBR */
-+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
-+#define GEOM_SYSCTL   "kern.geom.debugflags"
-+        int old_flags, flags;
-+        size_t sizeof_int = sizeof (int);
-+
-+        if (sysctlbyname (GEOM_SYSCTL, &old_flags, &sizeof_int, NULL, 0) != 0)
-+          grub_printf ("failed to get " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
-+
-+        if ((old_flags & 0x10) == 0)
-+          {
-+            /* "allow foot shooting", see geom(4) */
-+            flags = old_flags | 0x10;
-+
-+            if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &flags, sizeof (int)) != 0)
-+              {
-+                flags = old_flags;
-+                grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
-+              }
-+          }
-+        else
-+          flags = old_flags;
-+#endif
-+        disks[drive].flags = open (devname, O_RDWR);
-+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
-+        if (flags != old_flags)
-+          {
-+            if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &old_flags, sizeof (int)) != 0)
-+              grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
-+          }
-+#endif
-+      }
-       if (disks[drive].flags == -1)
-       {
-@@ -926,7 +1037,7 @@
- int
- biosdisk (int subfunc, int drive, struct geometry *geometry,
--        int sector, int nsec, int segment)
-+        unsigned int sector, int nsec, int segment)
- {
-   char *buf;
-   int fd = geometry->flags;
-diff -Nur grub-0.97/grub/asmstub.c.orig grub-0.97-patched/grub/asmstub.c.orig
---- grub-0.97/grub/asmstub.c.orig      1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/grub/asmstub.c.orig      2005-02-16 21:45:14.000000000 +0100
-@@ -0,0 +1,1275 @@
-+/* asmstub.c - a version of shared_src/asm.S that works under Unix */
-+/*
-+ *  GRUB  --  GRand Unified Bootloader
-+ *  Copyright (C) 1999,2000,2001,2002,2004  Free Software Foundation, Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+/* Try to use glibc's transparant LFS support. */
-+#define _LARGEFILE_SOURCE     1
-+/* lseek becomes synonymous with lseek64.  */
-+#define _FILE_OFFSET_BITS     64
-+
-+/* Simulator entry point. */
-+int grub_stage2 (void);
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <assert.h>
-+#include <stdio.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <time.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <setjmp.h>
-+#include <sys/time.h>
-+#include <termios.h>
-+#include <signal.h>
-+
-+#ifdef __linux__
-+# include <sys/ioctl.h>               /* ioctl */
-+# if !defined(__GLIBC__) || \
-+      ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
-+/* Maybe libc doesn't have large file support.  */
-+#  include <linux/unistd.h>   /* _llseek */
-+# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
-+# ifndef BLKFLSBUF
-+#  define BLKFLSBUF   _IO (0x12,97)   /* flush buffer cache */
-+# endif /* ! BLKFLSBUF */
-+#endif /* __linux__ */
-+
-+/* We want to prevent any circularararity in our stubs, as well as
-+   libc name clashes. */
-+#define WITHOUT_LIBC_STUBS 1
-+#include <shared.h>
-+#include <device.h>
-+#include <serial.h>
-+#include <term.h>
-+
-+/* Simulated memory sizes. */
-+#define EXTENDED_MEMSIZE (3 * 1024 * 1024)    /* 3MB */
-+#define CONVENTIONAL_MEMSIZE (640 * 1024)     /* 640kB */
-+
-+unsigned long install_partition = 0x20000;
-+unsigned long boot_drive = 0;
-+int saved_entryno = 0;
-+char version_string[] = VERSION;
-+char config_file[128] = "/boot/grub/menu.lst"; /* FIXME: arbitrary */
-+unsigned long linux_text_len = 0;
-+char *linux_data_tmp_addr = 0;
-+char *linux_data_real_addr = 0;
-+unsigned short io_map[IO_MAP_SIZE];
-+struct apm_info apm_bios_info;
-+
-+/* Emulation requirements. */
-+char *grub_scratch_mem = 0;
-+
-+struct geometry *disks = 0;
-+
-+/* The map between BIOS drives and UNIX device file names.  */
-+char **device_map = 0;
-+
-+/* The jump buffer for exiting correctly.  */
-+static jmp_buf env_for_exit;
-+
-+/* The current color for console.  */
-+int console_current_color = A_NORMAL;
-+
-+/* The file descriptor for a serial device.  */
-+static int serial_fd = -1;
-+
-+/* The file name of a serial device.  */
-+static char *serial_device = 0;
-+
-+#ifdef SIMULATE_SLOWNESS_OF_SERIAL
-+/* The speed of a serial device.  */
-+static unsigned int serial_speed;
-+#endif /* SIMULATE_SLOWNESS_OF_SERIAL */
-+
-+/* The main entry point into this mess. */
-+int
-+grub_stage2 (void)
-+{
-+  /* These need to be static, because they survive our stack transitions. */
-+  static int status = 0;
-+  static char *realstack;
-+  char *scratch, *simstack;
-+  int i;
-+
-+  auto void doit (void);
-+  
-+  /* We need a nested function so that we get a clean stack frame,
-+     regardless of how the code is optimized. */
-+  void doit (void)
-+    {
-+      /* Make sure our stack lives in the simulated memory area. */
-+      asm volatile ("movl %%esp, %0\n\tmovl %1, %%esp\n"
-+                  : "=&r" (realstack) : "r" (simstack));
-+      
-+      /* Do a setjmp here for the stop command.  */
-+      if (! setjmp (env_for_exit))
-+      {
-+        /* Actually enter the generic stage2 code.  */
-+        status = 0;
-+        init_bios_info ();
-+      }
-+      else
-+      {
-+        /* If ERRNUM is non-zero, then set STATUS to non-zero.  */
-+        if (errnum)
-+          status = 1;
-+      }
-+      
-+      /* Replace our stack before we use any local variables. */
-+      asm volatile ("movl %0, %%esp\n" : : "r" (realstack));
-+    }
-+
-+  assert (grub_scratch_mem == 0);
-+  scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
-+  assert (scratch);
-+  grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4);
-+
-+  /* FIXME: simulate the memory holes using mprot, if available. */
-+
-+  assert (disks == 0);
-+  disks = malloc (NUM_DISKS * sizeof (*disks));
-+  assert (disks);
-+  /* Initialize DISKS.  */
-+  for (i = 0; i < NUM_DISKS; i++)
-+    disks[i].flags = -1;
-+
-+  if (! init_device_map (&device_map, device_map_file, floppy_disks))
-+    return 1;
-+  
-+  /* Check some invariants. */
-+  assert ((SCRATCHSEG << 4) == SCRATCHADDR);
-+  assert ((BUFFERSEG << 4) == BUFFERADDR);
-+  assert (BUFFERADDR + BUFFERLEN == SCRATCHADDR);
-+  assert (FSYS_BUF % 16 == 0);
-+  assert (FSYS_BUF + FSYS_BUFLEN == BUFFERADDR);
-+
-+#ifdef HAVE_LIBCURSES
-+  /* Get into char-at-a-time mode. */
-+  if (use_curses)
-+    {
-+      initscr ();
-+      cbreak ();
-+      noecho ();
-+      nonl ();
-+      scrollok (stdscr, TRUE);
-+      keypad (stdscr, TRUE);
-+      wtimeout (stdscr, 100);
-+      signal (SIGWINCH, SIG_IGN);
-+    }
-+#endif
-+
-+  /* Make sure that actual writing is done.  */
-+  sync ();
-+
-+  /* Set our stack, and go for it. */
-+  simstack = (char *) PROTSTACKINIT;
-+  doit ();
-+
-+  /* I don't know if this is necessary really.  */
-+  sync ();
-+
-+#ifdef HAVE_LIBCURSES
-+  if (use_curses)
-+    endwin ();
-+#endif
-+
-+  /* Close off the file descriptors we used. */
-+  for (i = 0; i < NUM_DISKS; i ++)
-+    if (disks[i].flags != -1)
-+      {
-+#ifdef __linux__
-+      /* In Linux, invalidate the buffer cache. In other OSes, reboot
-+         is one of the solutions...  */
-+      ioctl (disks[i].flags, BLKFLSBUF, 0);
-+#else
-+# warning "In your operating system, the buffer cache will not be flushed."
-+#endif
-+      close (disks[i].flags);
-+      }
-+
-+  if (serial_fd >= 0)
-+    close (serial_fd);
-+  
-+  /* Release memory. */
-+  restore_device_map (device_map);
-+  device_map = 0;
-+  free (disks);
-+  disks = 0;
-+  free (scratch);
-+  grub_scratch_mem = 0;
-+
-+  if (serial_device)
-+    free (serial_device);
-+  serial_device = 0;
-+  
-+  /* Ahh... at last we're ready to return to caller. */
-+  return status;
-+}
-+
-+/* Assign DRIVE to a device name DEVICE.  */
-+void
-+assign_device_name (int drive, const char *device)
-+{
-+  /* If DRIVE is already assigned, free it.  */
-+  if (device_map[drive])
-+    free (device_map[drive]);
-+
-+  /* If the old one is already opened, close it.  */
-+  if (disks[drive].flags != -1)
-+    {
-+      close (disks[drive].flags);
-+      disks[drive].flags = -1;
-+    }
-+
-+  /* Assign DRIVE to DEVICE.  */
-+  if (! device)
-+    device_map[drive] = 0;
-+  else
-+    device_map[drive] = strdup (device);
-+}
-+
-+void
-+stop (void)
-+{
-+#ifdef HAVE_LIBCURSES
-+  if (use_curses)
-+    endwin ();
-+#endif
-+
-+  /* Jump to doit.  */
-+  longjmp (env_for_exit, 1);
-+}
-+
-+void
-+grub_reboot (void)
-+{
-+  stop ();
-+}
-+
-+void
-+grub_halt (int no_apm)
-+{
-+  stop ();
-+}
-+
-+/* calls for direct boot-loader chaining */
-+void
-+chain_stage1 (unsigned long segment, unsigned long offset,
-+            unsigned long part_table_addr)
-+{
-+  stop ();
-+}
-+
-+
-+void
-+chain_stage2 (unsigned long segment, unsigned long offset, int second_sector)
-+{
-+  stop ();
-+}
-+
-+
-+/* do some funky stuff, then boot linux */
-+void
-+linux_boot (void)
-+{
-+  stop ();
-+}
-+
-+
-+/* For bzImage kernels. */
-+void
-+big_linux_boot (void)
-+{
-+  stop ();
-+}
-+
-+
-+/* booting a multiboot executable */
-+void
-+multi_boot (int start, int mb_info)
-+{
-+  stop ();
-+}
-+
-+/* sets it to linear or wired A20 operation */
-+void
-+gateA20 (int linear)
-+{
-+  /* Nothing to do in the simulator. */
-+}
-+
-+/* Set up the int15 handler.  */
-+void
-+set_int15_handler (void)
-+{
-+  /* Nothing to do in the simulator.  */
-+}
-+
-+/* Restore the original int15 handler.  */
-+void
-+unset_int15_handler (void)
-+{
-+  /* Nothing to do in the simulator.  */
-+}
-+
-+/* The key map.  */
-+unsigned short bios_key_map[KEY_MAP_SIZE + 1];
-+unsigned short ascii_key_map[KEY_MAP_SIZE + 1];
-+
-+/* Copy MAP to the drive map and set up the int13 handler.  */
-+void
-+set_int13_handler (unsigned short *map)
-+{
-+  /* Nothing to do in the simulator.  */
-+}
-+
-+int
-+get_code_end (void)
-+{
-+  /* Just return a little area for simulation. */
-+  return BOOTSEC_LOCATION + (60 * 1024);
-+}
-+
-+
-+/* memory probe routines */
-+int
-+get_memsize (int type)
-+{
-+  if (! type)
-+    return CONVENTIONAL_MEMSIZE >> 10;
-+  else
-+    return EXTENDED_MEMSIZE >> 10;
-+}
-+
-+
-+/* get_eisamemsize() :  return packed EISA memory map, lower 16 bits is
-+ *            memory between 1M and 16M in 1K parts, upper 16 bits is
-+ *            memory above 16M in 64K parts.  If error, return -1.
-+ */
-+int
-+get_eisamemsize (void)
-+{
-+  return (EXTENDED_MEMSIZE >> 10);
-+}
-+
-+
-+#define MMAR_DESC_TYPE_AVAILABLE 1 /* available to OS */
-+#define MMAR_DESC_TYPE_RESERVED 2 /* not available */
-+#define MMAR_DESC_TYPE_ACPI_RECLAIM 3 /* usable by OS after reading ACPI */
-+#define MMAR_DESC_TYPE_ACPI_NVS 4 /* required to save between NVS sessions */
-+
-+#define MMAR_DESC_LENGTH      20
-+
-+/* Fetch the next entry in the memory map and return the continuation
-+   value.  DESC is a pointer to the descriptor buffer, and CONT is the
-+   previous continuation value (0 to get the first entry in the
-+   map).  */
-+int
-+get_mmap_entry (struct mmar_desc *desc, int cont)
-+{
-+  /* Record the memory map statically.  */
-+  static struct mmar_desc desc_table[] =
-+  {
-+    /* The conventional memory.  */
-+    {
-+      MMAR_DESC_LENGTH,
-+      0,
-+      CONVENTIONAL_MEMSIZE,
-+      MMAR_DESC_TYPE_AVAILABLE
-+    },
-+    /* BIOS RAM and ROM (such as video memory).  */
-+    {
-+      MMAR_DESC_LENGTH,
-+      CONVENTIONAL_MEMSIZE,
-+      0x100000 - CONVENTIONAL_MEMSIZE,
-+      MMAR_DESC_TYPE_RESERVED
-+    },
-+    /* The extended memory.  */
-+    {
-+      MMAR_DESC_LENGTH,
-+      0x100000,
-+      EXTENDED_MEMSIZE,
-+      MMAR_DESC_TYPE_AVAILABLE
-+    }
-+  };
-+  
-+  int num = sizeof (desc_table) / sizeof (*desc_table);
-+
-+  if (cont < 0 || cont >= num)
-+    {
-+      /* Should not happen.  */
-+      desc->desc_len = 0;
-+    }
-+  else
-+    {
-+      /* Copy the entry.  */
-+      *desc = desc_table[cont++];
-+
-+      /* If the next entry exists, return the index.  */
-+      if (cont < num)
-+      return cont;
-+    }
-+  
-+  return 0;
-+}
-+
-+/* Track the int13 handler.  */
-+void
-+track_int13 (int drive)
-+{
-+  /* Nothing to do in the simulator.  */
-+}
-+
-+/* Get the ROM configuration table.  */
-+unsigned long
-+get_rom_config_table (void)
-+{
-+  return 0;
-+}
-+
-+/* Get APM BIOS information.  */
-+void
-+get_apm_info (void)
-+{
-+  /* Nothing to do in the simulator.  */
-+}
-+
-+/* Get VBE controller information.  */
-+int
-+get_vbe_controller_info (struct vbe_controller *controller)
-+{
-+  /* Always fails.  */
-+  return 0;
-+}
-+
-+/* Get VBE mode information.  */
-+int
-+get_vbe_mode_info (int mode_number, struct vbe_mode *mode)
-+{
-+  /* Always fails.  */
-+  return 0;
-+}
-+
-+/* Set VBE mode.  */
-+int
-+set_vbe_mode (int mode_number)
-+{
-+  /* Always fails.  */
-+  return 0;
-+}
-+
-+/* low-level timing info */
-+int
-+getrtsecs (void)
-+{
-+  /* FIXME: exact value is not important, so just return time_t for now. */
-+  return time (0);
-+}
-+
-+int
-+currticks (void)
-+{
-+  struct timeval tv;
-+  long csecs;
-+  int ticks_per_csec, ticks_per_usec;
-+
-+  /* Note: 18.2 ticks/sec.  */
-+
-+  /* Get current time.  */
-+  gettimeofday (&tv, 0);
-+
-+  /* Compute centiseconds.  */
-+  csecs = tv.tv_sec / 10;
-+
-+  /* Ticks per centisecond.  */
-+  ticks_per_csec = csecs * 182;
-+
-+  /* Ticks per microsecond.  */
-+  ticks_per_usec = (((tv.tv_sec - csecs * 10) * 1000000 + tv.tv_usec)
-+                  * 182 / 10000000);
-+
-+  /* Sum them.  */
-+  return ticks_per_csec + ticks_per_usec;
-+}
-+
-+/* displays an ASCII character.  IBM displays will translate some
-+   characters to special graphical ones */
-+void
-+console_putchar (int c)
-+{
-+  /* Curses doesn't have VGA fonts.  */
-+  switch (c)
-+    {
-+    case DISP_UL:
-+      c = ACS_ULCORNER;
-+      break;
-+    case DISP_UR:
-+      c = ACS_URCORNER;
-+      break;
-+    case DISP_LL:
-+      c = ACS_LLCORNER;
-+      break;
-+    case DISP_LR:
-+      c = ACS_LRCORNER;
-+      break;
-+    case DISP_HORIZ:
-+      c = ACS_HLINE;
-+      break;
-+    case DISP_VERT:
-+      c = ACS_VLINE;
-+      break;
-+    case DISP_LEFT:
-+      c = ACS_LARROW;
-+      break;
-+    case DISP_RIGHT:
-+      c = ACS_RARROW;
-+      break;
-+    case DISP_UP:
-+      c = ACS_UARROW;
-+      break;
-+    case DISP_DOWN:
-+      c = ACS_DARROW;
-+      break;
-+    default:
-+      break;
-+    }
-+
-+#ifdef HAVE_LIBCURSES
-+  if (use_curses)
-+    {
-+      /* In ncurses, a newline is treated badly, so we emulate it in our
-+       own way.  */
-+      if (c == '\n')
-+      {
-+        int x, y;
-+
-+        getyx (stdscr, y, x);
-+        if (y + 1 == LINES)
-+          scroll (stdscr);
-+        else
-+          move (y + 1, x);
-+      }
-+      else if (isprint (c))
-+      {
-+        int x, y;
-+
-+        getyx (stdscr, y, x);
-+        if (x + 1 == COLS)
-+          {
-+            console_putchar ('\r');
-+            console_putchar ('\n');
-+          }
-+        addch (c | console_current_color);
-+      }
-+      else
-+      {
-+        addch (c);
-+      }
-+      
-+#ifdef REFRESH_IMMEDIATELY
-+      refresh ();
-+#endif
-+    }
-+  else
-+#endif
-+    {
-+      /* CR is not used in Unix.  */
-+      if (c != '\r')
-+      putchar (c);
-+    }
-+}
-+
-+/* The store for ungetch simulation. This is necessary, because
-+   ncurses-1.9.9g is still used in the world and its ungetch is
-+   completely broken.  */
-+#ifdef HAVE_LIBCURSES
-+static int save_char = ERR;
-+#endif
-+
-+static int
-+console_translate_key (int c)
-+{
-+  switch (c)
-+    {
-+    case KEY_LEFT:
-+      return 2;
-+    case KEY_RIGHT:
-+      return 6;
-+    case KEY_UP:
-+      return 16;
-+    case KEY_DOWN:
-+      return 14;
-+    case KEY_DC:
-+      return 4;
-+    case KEY_BACKSPACE:
-+      return 8;
-+    case KEY_HOME:
-+      return 1;
-+    case KEY_END:
-+      return 5;
-+    case KEY_PPAGE:
-+      return 7;
-+    case KEY_NPAGE:
-+      return 3;
-+    default:
-+      break;
-+    }
-+
-+  return c;
-+}
-+
-+/* like 'getkey', but doesn't wait, returns -1 if nothing available */
-+int
-+console_checkkey (void)
-+{
-+#ifdef HAVE_LIBCURSES
-+  if (use_curses)
-+    {
-+      int c;
-+
-+      /* Check for SAVE_CHAR. This should not be true, because this
-+       means checkkey is called twice continuously.  */
-+      if (save_char != ERR)
-+      return save_char;
-+
-+      c = getch ();
-+      /* If C is not ERR, then put it back in the input queue.  */
-+      if (c != ERR)
-+      save_char = c;
-+      return console_translate_key (c);
-+    }
-+#endif
-+
-+  /* Just pretend they hit the space bar, then read the real key when
-+     they call getkey. */
-+  return ' ';
-+}
-+
-+/* returns packed BIOS/ASCII code */
-+int
-+console_getkey (void)
-+{
-+  int c;
-+
-+#ifdef HAVE_LIBCURSES
-+  if (use_curses)
-+    {
-+      /* If checkkey has already got a character, then return it.  */
-+      if (save_char != ERR)
-+      {
-+        c = save_char;
-+        save_char = ERR;
-+        return console_translate_key (c);
-+      }
-+
-+      wtimeout (stdscr, -1);
-+      c = getch ();
-+      wtimeout (stdscr, 100);
-+    }
-+  else
-+#endif
-+    c = getchar ();
-+
-+  /* Quit if we get EOF. */
-+  if (c == -1)
-+    stop ();
-+  
-+  return console_translate_key (c);
-+}
-+
-+/* returns packed values, LSB+1 is x, LSB is y */
-+int
-+console_getxy (void)
-+{
-+  int y, x;
-+#ifdef HAVE_LIBCURSES
-+  if (use_curses)
-+    getyx (stdscr, y, x);
-+  else
-+#endif
-+  y = x = 0;
-+  return (x << 8) | (y & 0xff);
-+}
-+
-+void
-+console_gotoxy (int x, int y)
-+{
-+#ifdef HAVE_LIBCURSES
-+  if (use_curses)
-+    move (y, x);
-+#endif
-+}
-+
-+/* low-level character I/O */
-+void
-+console_cls (void)
-+{
-+#ifdef HAVE_LIBCURSES
-+  if (use_curses)
-+    clear ();
-+#endif
-+}
-+
-+void
-+console_setcolorstate (color_state state)
-+{
-+  console_current_color = 
-+    (state == COLOR_STATE_HIGHLIGHT) ? A_REVERSE : A_NORMAL;
-+}
-+
-+void
-+console_setcolor (int normal_color, int highlight_color)
-+{
-+  /* Nothing to do.  */
-+}
-+
-+int
-+console_setcursor (int on)
-+{
-+  return 1;
-+}
-+
-+/* Low-level disk I/O.  Our stubbed version just returns a file
-+   descriptor, not the actual geometry. */
-+int
-+get_diskinfo (int drive, struct geometry *geometry)
-+{
-+  /* FIXME: this function is truly horrid.  We try opening the device,
-+     then severely abuse the GEOMETRY->flags field to pass a file
-+     descriptor to biosdisk.  Thank God nobody's looking at this comment,
-+     or my reputation would be ruined. --Gord */
-+
-+  /* See if we have a cached device. */
-+  if (disks[drive].flags == -1)
-+    {
-+      /* The unpartitioned device name: /dev/XdX */
-+      char *devname = device_map[drive];
-+      char buf[512];
-+
-+      if (! devname)
-+      return -1;
-+
-+      if (verbose)
-+      grub_printf ("Attempt to open drive 0x%x (%s)\n",
-+                   drive, devname);
-+
-+      /* Open read/write, or read-only if that failed. */
-+      if (! read_only)
-+      disks[drive].flags = open (devname, O_RDWR);
-+
-+      if (disks[drive].flags == -1)
-+      {
-+        if (read_only || errno == EACCES || errno == EROFS || errno == EPERM)
-+          {
-+            disks[drive].flags = open (devname, O_RDONLY);
-+            if (disks[drive].flags == -1)
-+              {
-+                assign_device_name (drive, 0);
-+                return -1;
-+              }
-+          }
-+        else
-+          {
-+            assign_device_name (drive, 0);
-+            return -1;
-+          }
-+      }
-+
-+      /* Attempt to read the first sector.  */
-+      if (read (disks[drive].flags, buf, 512) != 512)
-+      {
-+        close (disks[drive].flags);
-+        disks[drive].flags = -1;
-+        assign_device_name (drive, 0);
-+        return -1;
-+      }
-+
-+      if (disks[drive].flags != -1)
-+      get_drive_geometry (&disks[drive], device_map, drive);
-+    }
-+
-+  if (disks[drive].flags == -1)
-+    return -1;
-+
-+#ifdef __linux__
-+  /* In Linux, invalidate the buffer cache, so that left overs
-+     from other program in the cache are flushed and seen by us */
-+  ioctl (disks[drive].flags, BLKFLSBUF, 0);
-+#endif
-+
-+  *geometry = disks[drive];
-+  return 0;
-+}
-+
-+/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an
-+   error occurs, otherwise return LEN.  */
-+static int
-+nread (int fd, char *buf, size_t len)
-+{
-+  int size = len;
-+
-+  while (len)
-+    {
-+      int ret = read (fd, buf, len);
-+
-+      if (ret <= 0)
-+      {
-+        if (errno == EINTR)
-+          continue;
-+        else
-+          return ret;
-+      }
-+
-+      len -= ret;
-+      buf += ret;
-+    }
-+
-+  return size;
-+}
-+
-+/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
-+   error occurs, otherwise return LEN.  */
-+static int
-+nwrite (int fd, char *buf, size_t len)
-+{
-+  int size = len;
-+
-+  while (len)
-+    {
-+      int ret = write (fd, buf, len);
-+
-+      if (ret <= 0)
-+      {
-+        if (errno == EINTR)
-+          continue;
-+        else
-+          return ret;
-+      }
-+
-+      len -= ret;
-+      buf += ret;
-+    }
-+
-+  return size;
-+}
-+
-+/* Dump BUF in the format of hexadecimal numbers.  */
-+static void
-+hex_dump (void *buf, size_t size)
-+{
-+  /* FIXME: How to determine which length is readable?  */
-+#define MAX_COLUMN    70
-+
-+  /* use unsigned char for numerical computations */
-+  unsigned char *ptr = buf;
-+  /* count the width of the line */
-+  int column = 0;
-+  /* how many bytes written */
-+  int count = 0;
-+
-+  while (size > 0)
-+    {
-+      /* high 4 bits */
-+      int hi = *ptr >> 4;
-+      /* low 4 bits */
-+      int low = *ptr & 0xf;
-+
-+      /* grub_printf does not handle prefix number, such as %2x, so
-+       format the number by hand...  */
-+      grub_printf ("%x%x", hi, low);
-+      column += 2;
-+      count++;
-+      ptr++;
-+      size--;
-+
-+      /* Insert space or newline with the interval 4 bytes.  */
-+      if (size != 0 && (count % 4) == 0)
-+      {
-+        if (column < MAX_COLUMN)
-+          {
-+            grub_printf (" ");
-+            column++;
-+          }
-+        else
-+          {
-+            grub_printf ("\n");
-+            column = 0;
-+          }
-+      }
-+    }
-+
-+  /* Add a newline at the end for readability.  */
-+  grub_printf ("\n");
-+}
-+
-+int
-+biosdisk (int subfunc, int drive, struct geometry *geometry,
-+        int sector, int nsec, int segment)
-+{
-+  char *buf;
-+  int fd = geometry->flags;
-+
-+  /* Get the file pointer from the geometry, and make sure it matches. */
-+  if (fd == -1 || fd != disks[drive].flags)
-+    return BIOSDISK_ERROR_GEOMETRY;
-+
-+  /* Seek to the specified location. */
-+#if defined(__linux__) && (!defined(__GLIBC__) || \
-+      ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
-+  /* Maybe libc doesn't have large file support.  */
-+  {
-+    loff_t offset, result;
-+    static int _llseek (uint filedes, ulong hi, ulong lo,
-+                      loff_t *res, uint wh);
-+    _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
-+             loff_t *, res, uint, wh);
-+
-+    offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
-+    if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
-+      return -1;
-+  }
-+#else
-+  {
-+    off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
-+
-+    if (lseek (fd, offset, SEEK_SET) != offset)
-+      return -1;
-+  }
-+#endif
-+
-+  buf = (char *) (segment << 4);
-+
-+  switch (subfunc)
-+    {
-+    case BIOSDISK_READ:
-+#ifdef __linux__
-+      if (sector == 0 && nsec > 1)
-+      {
-+        /* Work around a bug in linux's ez remapping.  Linux remaps all
-+           sectors that are read together with the MBR in one read.  It
-+           should only remap the MBR, so we split the read in two 
-+           parts. -jochen  */
-+        if (nread (fd, buf, SECTOR_SIZE) != SECTOR_SIZE)
-+          return -1;
-+        buf += SECTOR_SIZE;
-+        nsec--;
-+      }
-+#endif
-+      if (nread (fd, buf, nsec * SECTOR_SIZE) != nsec * SECTOR_SIZE)
-+      return -1;
-+      break;
-+
-+    case BIOSDISK_WRITE:
-+      if (verbose)
-+      {
-+        grub_printf ("Write %d sectors starting from %d sector"
-+                     " to drive 0x%x (%s)\n",
-+                     nsec, sector, drive, device_map[drive]);
-+        hex_dump (buf, nsec * SECTOR_SIZE);
-+      }
-+      if (! read_only)
-+      if (nwrite (fd, buf, nsec * SECTOR_SIZE) != nsec * SECTOR_SIZE)
-+        return -1;
-+      break;
-+
-+    default:
-+      grub_printf ("unknown subfunc %d\n", subfunc);
-+      break;
-+    }
-+
-+  return 0;
-+}
-+
-+
-+void
-+stop_floppy (void)
-+{
-+  /* NOTUSED */
-+}
-+
-+/* Fetch a key from a serial device.  */
-+int
-+serial_hw_fetch (void)
-+{
-+  fd_set fds;
-+  struct timeval to;
-+  char c;
-+
-+  /* Wait only for the serial device.  */
-+  FD_ZERO (&fds);
-+  FD_SET (serial_fd, &fds);
-+
-+  to.tv_sec = 0;
-+  to.tv_usec = 0;
-+  
-+  if (select (serial_fd + 1, &fds, 0, 0, &to) > 0)
-+    {
-+      if (nread (serial_fd, &c, 1) != 1)
-+      stop ();
-+
-+      return c;
-+    }
-+  
-+  return -1;
-+}
-+
-+/* Put a character to a serial device.  */
-+void
-+serial_hw_put (int c)
-+{
-+  char ch = (char) c;
-+  
-+  if (nwrite (serial_fd, &ch, 1) != 1)
-+    stop ();
-+}
-+
-+void
-+serial_hw_delay (void)
-+{
-+#ifdef SIMULATE_SLOWNESS_OF_SERIAL
-+  struct timeval otv, tv;
-+
-+  gettimeofday (&otv, 0);
-+
-+  while (1)
-+    {
-+      long delta;
-+      
-+      gettimeofday (&tv, 0);
-+      delta = tv.tv_usec - otv.tv_usec;
-+      if (delta < 0)
-+      delta += 1000000;
-+      
-+      if (delta >= 1000000 / (serial_speed >> 3))
-+      break;
-+    }
-+#endif /* SIMULATE_SLOWNESS_OF_SERIAL */
-+}
-+
-+static speed_t
-+get_termios_speed (int speed)
-+{
-+  switch (speed)
-+    {
-+    case 2400: return B2400;
-+    case 4800: return B4800;
-+    case 9600: return B9600;
-+    case 19200: return B19200;
-+    case 38400: return B38400;
-+#ifdef B57600
-+    case 57600: return B57600;
-+#endif
-+#ifdef B115200      
-+    case 115200: return B115200;
-+#endif
-+    }
-+
-+  return B0;
-+}
-+
-+/* Get the port number of the unit UNIT. In the grub shell, this doesn't
-+   make sense.  */
-+unsigned short
-+serial_hw_get_port (int unit)
-+{
-+  return 0;
-+}
-+
-+/* Initialize a serial device. In the grub shell, PORT is unused.  */
-+int
-+serial_hw_init (unsigned short port, unsigned int speed,
-+              int word_len, int parity, int stop_bit_len)
-+{
-+  struct termios termios;
-+  speed_t termios_speed;
-+  int i;
-+  
-+  /* Check if the file name is specified.  */
-+  if (! serial_device)
-+    return 0;
-+
-+  /* If a serial device is already opened, close it first.  */
-+  if (serial_fd >= 0)
-+    close (serial_fd);
-+  
-+  /* Open the device file.  */
-+  serial_fd = open (serial_device,
-+                  O_RDWR | O_NOCTTY
-+#if defined(O_SYNC)
-+                  /* O_SYNC is used in Linux (and some others?).  */
-+                  | O_SYNC
-+#elif defined(O_FSYNC)
-+                  /* O_FSYNC is used in FreeBSD.  */
-+                  | O_FSYNC
-+#endif
-+                  );
-+  if (serial_fd < 0)
-+    return 0;
-+
-+  /* Get the termios parameters.  */
-+  if (tcgetattr (serial_fd, &termios))
-+    goto fail;
-+
-+  /* Raw mode.  */
-+  cfmakeraw (&termios);
-+
-+  /* Set the speed.  */
-+  termios_speed = get_termios_speed (speed);
-+  if (termios_speed == B0)
-+    goto fail;
-+  
-+  cfsetispeed (&termios, termios_speed);
-+  cfsetospeed (&termios, termios_speed);
-+
-+  /* Set the word length.  */
-+  termios.c_cflag &= ~CSIZE;
-+  switch (word_len)
-+    {
-+    case UART_5BITS_WORD:
-+      termios.c_cflag |= CS5;
-+      break;
-+    case UART_6BITS_WORD:
-+      termios.c_cflag |= CS6;
-+      break;
-+    case UART_7BITS_WORD:
-+      termios.c_cflag |= CS7;
-+      break;
-+    case UART_8BITS_WORD:
-+      termios.c_cflag |= CS8;
-+      break;
-+    default:
-+      goto fail;
-+    }
-+
-+  /* Set the parity.  */
-+  switch (parity)
-+    {
-+    case UART_NO_PARITY:
-+      termios.c_cflag &= ~PARENB;
-+      break;
-+    case UART_ODD_PARITY:
-+      termios.c_cflag |= PARENB;
-+      termios.c_cflag |= PARODD;
-+      break;
-+    case UART_EVEN_PARITY:
-+      termios.c_cflag |= PARENB;
-+      termios.c_cflag &= ~PARODD;
-+      break;
-+    default:
-+      goto fail;
-+    }
-+
-+  /* Set the length of stop bit.  */
-+  switch (stop_bit_len)
-+    {
-+    case UART_1_STOP_BIT:
-+      termios.c_cflag &= ~CSTOPB;
-+      break;
-+    case UART_2_STOP_BITS:
-+      termios.c_cflag |= CSTOPB;
-+      break;
-+    default:
-+      goto fail;
-+    }
-+
-+  /* Set the parameters.  */
-+  if (tcsetattr (serial_fd, TCSANOW, &termios))
-+    goto fail;
-+
-+#ifdef SIMULATE_SLOWNESS_OF_SERIAL
-+  serial_speed = speed;
-+#endif /* SIMUATE_SLOWNESS_OF_SERIAL */
-+
-+  /* Get rid of the flag TERM_NEED_INIT from the serial terminal.  */
-+  for (i = 0; term_table[i].name; i++)
-+    {
-+      if (strcmp (term_table[i].name, "serial") == 0)
-+      {
-+        term_table[i].flags &= ~(TERM_NEED_INIT);
-+        break;
-+      }
-+    }
-+  
-+  return 1;
-+
-+ fail:
-+  close (serial_fd);
-+  serial_fd = -1;
-+  return 0;
-+}
-+
-+/* Set the file name of a serial device (or a pty device). This is a
-+   function specific to the grub shell.  */
-+void
-+serial_set_device (const char *device)
-+{
-+  if (serial_device)
-+    free (serial_device);
-+  
-+  serial_device = strdup (device);
-+}
-+
-+/* There is no difference between console and hercules in the grub shell.  */
-+void
-+hercules_putchar (int c)
-+{
-+  console_putchar (c);
-+}
-+
-+int
-+hercules_getxy (void)
-+{
-+  return console_getxy ();
-+}
-+
-+void
-+hercules_gotoxy (int x, int y)
-+{
-+  console_gotoxy (x, y);
-+}
-+
-+void
-+hercules_cls (void)
-+{
-+  console_cls ();
-+}
-+
-+void
-+hercules_setcolorstate (color_state state)
-+{
-+  console_setcolorstate (state);
-+}
-+
-+void
-+hercules_setcolor (int normal_color, int highlight_color)
-+{
-+  console_setcolor (normal_color, highlight_color);
-+}
-+
-+int
-+hercules_setcursor (int on)
-+{
-+  return 1;
-+}
-diff -Nur grub-0.97/grub/main.c grub-0.97-patched/grub/main.c
---- grub-0.97/grub/main.c      2003-07-09 13:45:36.000000000 +0200
-+++ grub-0.97-patched/grub/main.c      2012-11-11 17:07:12.720729374 +0100
-@@ -32,6 +32,7 @@
- #define WITHOUT_LIBC_STUBS 1
- #include <shared.h>
- #include <term.h>
-+#include <device.h>
- char *program_name = 0;
- int use_config_file = 1;
-@@ -140,10 +141,7 @@
-   program_name = argv[0];
-   default_boot_drive = boot_drive;
-   default_install_partition = install_partition;
--  if (config_file)
--    default_config_file = config_file;
--  else
--    default_config_file = "NONE";
-+  default_config_file = config_file;
-   
-   /* Parse command-line options. */
-   do
-@@ -192,6 +190,12 @@
-             perror ("strtoul");
-             exit (1);
-           }
-+        if (boot_drive >= NUM_DISKS)
-+          {
-+            fprintf (stderr, "boot_drive should be from 0 to %d\n",
-+                     NUM_DISKS - 1);
-+            exit (1);
-+          }
-         break;
-       case OPT_NO_CONFIG_FILE:
-diff -Nur grub-0.97/grub/main.c.orig grub-0.97-patched/grub/main.c.orig
---- grub-0.97/grub/main.c.orig 1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/grub/main.c.orig 2003-07-09 13:45:36.000000000 +0200
-@@ -0,0 +1,265 @@
-+/* main.c - experimental GRUB stage2 that runs under Unix */
-+/*
-+ *  GRUB  --  GRand Unified Bootloader
-+ *  Copyright (C) 1999,2000,2001,2002  Free Software Foundation, Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+/* Simulator entry point. */
-+int grub_stage2 (void);
-+
-+#include <stdio.h>
-+#include <getopt.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <limits.h>
-+#include <setjmp.h>
-+
-+#define WITHOUT_LIBC_STUBS 1
-+#include <shared.h>
-+#include <term.h>
-+
-+char *program_name = 0;
-+int use_config_file = 1;
-+int use_preset_menu = 0;
-+#ifdef HAVE_LIBCURSES
-+int use_curses = 1;
-+#else
-+int use_curses = 0;
-+#endif
-+int verbose = 0;
-+int read_only = 0;
-+int floppy_disks = 1;
-+char *device_map_file = 0;
-+static int default_boot_drive;
-+static int default_install_partition;
-+static char *default_config_file;
-+
-+#define OPT_HELP              -2
-+#define OPT_VERSION           -3
-+#define OPT_HOLD              -4
-+#define OPT_CONFIG_FILE               -5
-+#define OPT_INSTALL_PARTITION -6
-+#define OPT_BOOT_DRIVE                -7
-+#define OPT_NO_CONFIG_FILE    -8
-+#define OPT_NO_CURSES         -9
-+#define OPT_BATCH             -10
-+#define OPT_VERBOSE           -11
-+#define OPT_READ_ONLY         -12
-+#define OPT_PROBE_SECOND_FLOPPY       -13
-+#define OPT_NO_FLOPPY         -14
-+#define OPT_DEVICE_MAP                -15
-+#define OPT_PRESET_MENU               -16
-+#define OPT_NO_PAGER          -17
-+#define OPTSTRING ""
-+
-+static struct option longopts[] =
-+{
-+  {"batch", no_argument, 0, OPT_BATCH},
-+  {"boot-drive", required_argument, 0, OPT_BOOT_DRIVE},
-+  {"config-file", required_argument, 0, OPT_CONFIG_FILE},
-+  {"device-map", required_argument, 0, OPT_DEVICE_MAP},
-+  {"help", no_argument, 0, OPT_HELP},
-+  {"hold", optional_argument, 0, OPT_HOLD},
-+  {"install-partition", required_argument, 0, OPT_INSTALL_PARTITION},
-+  {"no-config-file", no_argument, 0, OPT_NO_CONFIG_FILE},
-+  {"no-curses", no_argument, 0, OPT_NO_CURSES},
-+  {"no-floppy", no_argument, 0, OPT_NO_FLOPPY},
-+  {"no-pager", no_argument, 0, OPT_NO_PAGER},
-+  {"preset-menu", no_argument, 0, OPT_PRESET_MENU},
-+  {"probe-second-floppy", no_argument, 0, OPT_PROBE_SECOND_FLOPPY},
-+  {"read-only", no_argument, 0, OPT_READ_ONLY},
-+  {"verbose", no_argument, 0, OPT_VERBOSE},
-+  {"version", no_argument, 0, OPT_VERSION},
-+  {0},
-+};
-+
-+
-+static void
-+usage (int status)
-+{
-+  if (status)
-+    fprintf (stderr, "Try ``grub --help'' for more information.\n");
-+  else
-+    printf ("\
-+Usage: grub [OPTION]...\n\
-+\n\
-+Enter the GRand Unified Bootloader command shell.\n\
-+\n\
-+    --batch                  turn on batch mode for non-interactive use\n\
-+    --boot-drive=DRIVE       specify stage2 boot_drive [default=0x%x]\n\
-+    --config-file=FILE       specify stage2 config_file [default=%s]\n\
-+    --device-map=FILE        use the device map file FILE\n\
-+    --help                   display this message and exit\n\
-+    --hold                   wait until a debugger will attach\n\
-+    --install-partition=PAR  specify stage2 install_partition [default=0x%x]\n\
-+    --no-config-file         do not use the config file\n\
-+    --no-curses              do not use curses\n\
-+    --no-floppy              do not probe any floppy drive\n\
-+    --no-pager               do not use internal pager\n\
-+    --preset-menu            use the preset menu\n\
-+    --probe-second-floppy    probe the second floppy drive\n\
-+    --read-only              do not write anything to devices\n\
-+    --verbose                print verbose messages\n\
-+    --version                print version information and exit\n\
-+\n\
-+Report bugs to <bug-grub@gnu.org>.\n\
-+",
-+          default_boot_drive, default_config_file,
-+          default_install_partition);
-+
-+  exit (status);
-+}
-+
-+
-+int
-+main (int argc, char **argv)
-+{
-+  int c;
-+  int hold = 0;
-+
-+  /* First of all, call sync so that all in-core data is scheduled to be
-+     actually written to disks. This is very important because GRUB does
-+     not use ordinary stdio interface but raw devices.  */
-+  sync ();
-+  
-+  program_name = argv[0];
-+  default_boot_drive = boot_drive;
-+  default_install_partition = install_partition;
-+  if (config_file)
-+    default_config_file = config_file;
-+  else
-+    default_config_file = "NONE";
-+  
-+  /* Parse command-line options. */
-+  do
-+    {
-+      c = getopt_long (argc, argv, OPTSTRING, longopts, 0);
-+      switch (c)
-+      {
-+      case EOF:
-+        /* Fall through the bottom of the loop. */
-+        break;
-+
-+      case OPT_HELP:
-+        usage (0);
-+        break;
-+
-+      case OPT_VERSION:
-+        printf ("grub (GNU GRUB " VERSION ")\n");
-+        exit (0);
-+        break;
-+
-+      case OPT_HOLD:
-+        if (! optarg)
-+          hold = -1;
-+        else
-+          hold = atoi (optarg);
-+        break;
-+
-+      case OPT_CONFIG_FILE:
-+        strncpy (config_file, optarg, 127); /* FIXME: arbitrary */
-+        config_file[127] = '\0';
-+        break;
-+
-+      case OPT_INSTALL_PARTITION:
-+        install_partition = strtoul (optarg, 0, 0);
-+        if (install_partition == ULONG_MAX)
-+          {
-+            perror ("strtoul");
-+            exit (1);
-+          }
-+        break;
-+
-+      case OPT_BOOT_DRIVE:
-+        boot_drive = strtoul (optarg, 0, 0);
-+        if (boot_drive == ULONG_MAX)
-+          {
-+            perror ("strtoul");
-+            exit (1);
-+          }
-+        break;
-+
-+      case OPT_NO_CONFIG_FILE:
-+        use_config_file = 0;
-+        break;
-+
-+      case OPT_NO_CURSES:
-+        use_curses = 0;
-+        break;
-+
-+      case OPT_NO_PAGER:
-+        use_pager = 0;
-+        break;
-+
-+      case OPT_BATCH:
-+        /* This is the same as "--no-config-file --no-curses --no-pager".  */
-+        use_config_file = 0;
-+        use_curses = 0;
-+        use_pager = 0;
-+        break;
-+
-+      case OPT_READ_ONLY:
-+        read_only = 1;
-+        break;
-+
-+      case OPT_VERBOSE:
-+        verbose = 1;
-+        break;
-+
-+      case OPT_NO_FLOPPY:
-+        floppy_disks = 0;
-+        break;
-+
-+      case OPT_PROBE_SECOND_FLOPPY:
-+        floppy_disks = 2;
-+        break;
-+
-+      case OPT_DEVICE_MAP:
-+        device_map_file = strdup (optarg);
-+        break;
-+
-+      case OPT_PRESET_MENU:
-+        use_preset_menu = 1;
-+        break;
-+        
-+      default:
-+        usage (1);
-+      }
-+    }
-+  while (c != EOF);
-+
-+  /* Wait until the HOLD variable is cleared by an attached debugger. */
-+  if (hold && verbose)
-+    printf ("Run \"gdb %s %d\", and set HOLD to zero.\n",
-+          program_name, (int) getpid ());
-+  while (hold)
-+    {
-+      if (hold > 0)
-+      hold--;
-+      
-+      sleep (1);
-+    }
-+
-+  /* If we don't have curses (!HAVE_LIBCURSES or --no-curses or
-+     --batch) put terminal to dumb for better handling of line i/o */
-+  if (! use_curses)
-+    current_term->flags = TERM_NO_EDIT | TERM_DUMB;
-+
-+  /* Transfer control to the stage2 simulator. */
-+  exit (grub_stage2 ());
-+}
-diff -Nur grub-0.97/lib/device.c grub-0.97-patched/lib/device.c
---- grub-0.97/lib/device.c     2005-03-28 01:14:25.000000000 +0200
-+++ grub-0.97-patched/lib/device.c     2012-11-11 17:07:12.748730268 +0100
-@@ -69,9 +69,9 @@
- # ifndef CDROM_GET_CAPABILITY
- #  define CDROM_GET_CAPABILITY        0x5331  /* get capabilities */
- # endif /* ! CDROM_GET_CAPABILITY */
--# ifndef BLKGETSIZE
--#  define BLKGETSIZE  _IO(0x12,96)    /* return device size */
--# endif /* ! BLKGETSIZE */
-+# ifndef BLKGETSIZE64
-+#  define BLKGETSIZE64        _IOR(0x12,114,size_t)   /* return device size */
-+# endif /* ! BLKGETSIZE64 */
- #endif /* __linux__ */
- /* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with
-@@ -131,6 +131,152 @@
- #include <shared.h>
- #include <device.h>
-+#if defined(__linux__)
-+/* The 2.6 kernel has removed all of the geometry handling for IDE drives
-+ * that did fixups for LBA, etc.  This means that the geometry we get
-+ * with the ioctl has a good chance of being wrong.  So, we get to 
-+ * also know about partition tables and try to read what the geometry
-+ * is there. *grumble*   Very closely based on code from cfdisk
-+ */
-+static void get_kernel_geometry(int fd, long long *cyl, int *heads, int *sectors) {
-+    struct hd_geometry hdg;
-+    
-+    if (ioctl (fd, HDIO_GETGEO, &hdg))
-+        return;
-+
-+    *cyl = hdg.cylinders;
-+    *heads = hdg.heads;
-+    *sectors = hdg.sectors;
-+}
-+
-+struct partition {
-+        unsigned char boot_ind;         /* 0x80 - active */
-+        unsigned char head;             /* starting head */
-+        unsigned char sector;           /* starting sector */
-+        unsigned char cyl;              /* starting cylinder */
-+        unsigned char sys_ind;          /* What partition type */
-+        unsigned char end_head;         /* end head */
-+        unsigned char end_sector;       /* end sector */
-+        unsigned char end_cyl;          /* end cylinder */
-+        unsigned char start4[4];        /* starting sector counting from 0 */
-+        unsigned char size4[4];         /* nr of sectors in partition */
-+};
-+
-+#define ALIGNMENT 2
-+typedef union {
-+    struct {
-+      unsigned char align[ALIGNMENT];
-+      unsigned char b[SECTOR_SIZE];
-+    } c;
-+    struct {
-+      unsigned char align[ALIGNMENT];
-+      unsigned char buffer[0x1BE];
-+      struct partition part[4];
-+      unsigned char magicflag[2];
-+    } p;
-+} partition_table;
-+
-+#define PART_TABLE_FLAG0 0x55
-+#define PART_TABLE_FLAG1 0xAA
-+
-+static void
-+get_partition_table_geometry(partition_table *bufp, long long *cyl, int *heads, 
-+                             int *sectors) {
-+    struct partition *p;
-+    int i,h,s,hh,ss;
-+    int first = 1;
-+    int bad = 0;
-+
-+    if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 ||
-+      bufp->p.magicflag[1] != PART_TABLE_FLAG1) {
-+          /* Matthew Wilcox: slightly friendlier version of
-+             fatal(_("Bad signature on partition table"), 3);
-+          */
-+            fprintf(stderr, "Unknown partition table signature\n");
-+          return;
-+    }
-+
-+    hh = ss = 0;
-+    for (i=0; i<4; i++) {
-+      p = &(bufp->p.part[i]);
-+      if (p->sys_ind != 0) {
-+          h = p->end_head + 1;
-+          s = (p->end_sector & 077);
-+          if (first) {
-+              hh = h;
-+              ss = s;
-+              first = 0;
-+          } else if (hh != h || ss != s)
-+              bad = 1;
-+      }
-+    }
-+
-+    if (!first && !bad) {
-+      *heads = hh;
-+      *sectors = ss;
-+    }
-+}
-+
-+static long long my_lseek (unsigned int fd, long long offset, 
-+                           unsigned int origin)
-+{
-+#if defined(__linux__) && (!defined(__GLIBC__) || \
-+        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
-+  /* Maybe libc doesn't have large file support.  */
-+  loff_t offset, result;
-+  static int _llseek (uint filedes, ulong hi, ulong lo,
-+                      loff_t *res, uint wh);
-+  _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
-+             loff_t *, res, uint, wh);
-+  
-+  if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET) < 0)
-+    return (long long) -1;
-+  return result;
-+#else
-+  return lseek(fd, offset, SEEK_SET);
-+#endif
-+}
-+
-+static void get_linux_geometry (int fd, struct geometry *geom) {
-+    long long kern_cyl = 0; int kern_head = 0, kern_sectors = 0;
-+    long long pt_cyl = 0; int pt_head = 0, pt_sectors = 0;
-+    partition_table bufp;
-+    char *buff, *buf_unaligned;
-+
-+    buf_unaligned = malloc(sizeof(partition_table) + 4095);
-+    buff = (char *) (((unsigned long)buf_unaligned + 4096 - 1) &
-+                     (~(4096-1)));
-+
-+    get_kernel_geometry(fd, &kern_cyl, &kern_head, &kern_sectors);
-+
-+    if (my_lseek (fd, 0*SECTOR_SIZE, SEEK_SET) < 0) {
-+        fprintf(stderr, "Unable to seek");
-+    }
-+
-+    if (read(fd, buff, SECTOR_SIZE) == SECTOR_SIZE) {
-+        memcpy(bufp.c.b, buff, SECTOR_SIZE);
-+        get_partition_table_geometry(&bufp, &pt_cyl, &pt_head, &pt_sectors);
-+    } else {
-+        fprintf(stderr, "Unable to read partition table: %s\n", strerror(errno));
-+    }
-+
-+    if (pt_head && pt_sectors) {
-+        int cyl_size;
-+
-+        geom->heads = pt_head;
-+        geom->sectors = pt_sectors;
-+        cyl_size = pt_head * pt_sectors;
-+        geom->cylinders = geom->total_sectors/cyl_size;
-+    } else {
-+        geom->heads = kern_head;
-+        geom->sectors = kern_sectors;
-+        geom->cylinders = kern_cyl;
-+    }
-+
-+    return;
-+}
-+#endif
-+
- /* Get the geometry of a drive DRIVE.  */
- void
- get_drive_geometry (struct geometry *geom, char **map, int drive)
-@@ -151,20 +297,16 @@
- #if defined(__linux__)
-   /* Linux */
-   {
--    struct hd_geometry hdg;
--    unsigned long nr;
-+    unsigned long long nr;
-     
--    if (ioctl (fd, HDIO_GETGEO, &hdg))
--      goto fail;
--
--    if (ioctl (fd, BLKGETSIZE, &nr))
-+    if (ioctl (fd, BLKGETSIZE64, &nr))
-       goto fail;
-     
-     /* Got the geometry, so save it. */
--    geom->cylinders = hdg.cylinders;
--    geom->heads = hdg.heads;
--    geom->sectors = hdg.sectors;
--    geom->total_sectors = nr;
-+    get_linux_geometry(fd, geom);
-+    if (!geom->heads && !geom->cylinders && !geom->sectors)
-+      goto fail;
-+    geom->total_sectors = nr / 512;
-     
-     goto success;
-   }
-@@ -403,10 +545,28 @@
- }
- static void
-+get_cciss_disk_name (char *name, int controller, int drive)
-+{
-+  sprintf (name, "/dev/cciss/c%dd%d", controller, drive);
-+}
-+
-+static void
-+get_ida_disk_name (char *name, int controller, int drive)
-+{
-+  sprintf (name, "/dev/ida/c%dd%d", controller, drive);
-+}
-+
-+static void
- get_ataraid_disk_name (char *name, int unit)
- {
-   sprintf (name, "/dev/ataraid/d%c", unit + '0');
- }
-+
-+static void
-+get_i2o_disk_name (char *name, char unit)
-+{
-+  sprintf (name, "/dev/i2o/hd%c", unit);
-+}
- #endif
- /* Check if DEVICE can be read. If an error occurs, return zero,
-@@ -801,6 +961,97 @@
-         }
-       }
-   }
-+    
-+  /* This is for I2O - we have /dev/i2o/hd<logical drive><partition> */
-+  {
-+    int unit;
-+
-+    for (unit = 'a'; unit < 'f'; unit++)
-+      {
-+        char name[24];
-+    
-+        get_i2o_disk_name (name, unit);
-+        if (check_device (name))
-+          {
-+              (*map)[num_hd + 0x80] = strdup (name);
-+                  assert ((*map)[num_hd + 0x80]);
-+                  
-+          /* If the device map file is opened, write the map.  */
-+               if (fp)
-+                     fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
-+                     
-+          num_hd++;
-+          }
-+      }
-+  }
-+
-+  /* This is for CCISS, its like the DAC960  - we have
-+     /dev/cciss/<controller>d<logical drive>p<partition> 
-+
-+     It currently supports up to 3 controllers, 10 logical volumes
-+     and 10 partitions
-+
-+     Code gratuitously copied from DAC960 above.
-+     Horms <horms@verge.net.au> 23rd July 2004
-+  */
-+  {
-+    int controller, drive;
-+    
-+    for (controller = 0; controller < 2; controller++)
-+      {
-+      for (drive = 0; drive < 9; drive++)
-+        {
-+          char name[24];
-+          
-+          get_cciss_disk_name (name, controller, drive);
-+          if (check_device (name))
-+            {
-+              (*map)[num_hd + 0x80] = strdup (name);
-+              assert ((*map)[num_hd + 0x80]);
-+              
-+              /* If the device map file is opened, write the map.  */
-+              if (fp)
-+                fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
-+              
-+              num_hd++;
-+            }
-+        }
-+      }
-+  }
-+
-+  /* This is for Compaq Smart Array, its like the DAC960  - we have
-+     /dev/ida/<controller>d<logical drive>p<partition> 
-+
-+     It currently supports up to 3 controllers, 10 logical volumes
-+     and 15 partitions
-+
-+     Code gratuitously copied from DAC960 above.
-+     Piotr Roszatycki <dexter@debian.org>
-+  */
-+  {
-+    int controller, drive;
-+    
-+    for (controller = 0; controller < 2; controller++)
-+      {
-+      for (drive = 0; drive < 9; drive++)
-+        {
-+          char name[24];
-+          
-+          get_ida_disk_name (name, controller, drive);
-+          if (check_device (name))
-+            {
-+              (*map)[num_hd + 0x80] = strdup (name);
-+              assert ((*map)[num_hd + 0x80]);
-+              
-+              /* If the device map file is opened, write the map.  */
-+              if (fp)
-+                fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
-+              
-+              num_hd++;
-+            }
-+        }
-+      }
-+  }
- #endif /* __linux__ */
-   
-   /* OK, close the device map file if opened.  */
-@@ -844,6 +1095,7 @@
- {
-   char dev[PATH_MAX]; /* XXX */
-   int fd;
-+  off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
-   
-   if ((partition & 0x00FF00) != 0x00FF00)
-     {
-@@ -861,6 +1113,14 @@
-       if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
-       strcpy (dev + strlen(dev) - 5, "/part");
-     }
-+  else
-+    {
-+      if ((strncmp (dev, "/dev/ataraid/", 13) == 0) ||
-+         (strncmp (dev, "/dev/ida/", 9) == 0) ||
-+         (strncmp (dev, "/dev/cciss/", 11) == 0) ||
-+         (strncmp (dev, "/dev/rd/", 8) == 0))
-+        strcpy (dev + strlen(dev), "p");
-+    }
-   sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
-   
-   /* Open the partition.  */
-@@ -870,35 +1130,13 @@
-       errnum = ERR_NO_PART;
-       return 0;
-     }
--  
--#if defined(__linux__) && (!defined(__GLIBC__) || \
--        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
--  /* Maybe libc doesn't have large file support.  */
--  {
--    loff_t offset, result;
--    static int _llseek (uint filedes, ulong hi, ulong lo,
--                        loff_t *res, uint wh);
--    _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
--               loff_t *, res, uint, wh);
--    offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
--    if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
--      {
--      errnum = ERR_DEV_VALUES;
--      return 0;
--      }
--  }
--#else
--  {
--    off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
--    if (lseek (fd, offset, SEEK_SET) != offset)
--      {
--      errnum = ERR_DEV_VALUES;
--      return 0;
--      }
--  }
--#endif
-+  if (my_lseek(fd, offset, SEEK_SET) != offset)
-+    {
-+      errnum = ERR_DEV_VALUES;
-+      return 0;
-+    }
-   
-   if (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE))
-     {
-diff -Nur grub-0.97/netboot/cs89x0.c grub-0.97-patched/netboot/cs89x0.c
---- grub-0.97/netboot/cs89x0.c 2003-07-09 13:45:37.000000000 +0200
-+++ grub-0.97-patched/netboot/cs89x0.c 2012-11-11 17:07:12.722729437 +0100
-@@ -1,3 +1,21 @@
-+/**
-+   Per an email message from Russ Nelson <nelson@crynwr.com> on
-+   18 March 2008 this file is now licensed under GPL Version 2.
-+
-+   From: Russ Nelson <nelson@crynwr.com>
-+   Date: Tue, 18 Mar 2008 12:42:00 -0400
-+   Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot
-+   -- quote from email
-+   As copyright holder, if I say it doesn't conflict with the GPL,
-+   then it doesn't conflict with the GPL.
-+
-+   However, there's no point in causing people's brains to overheat,
-+   so yes, I grant permission for the code to be relicensed under the
-+   GPLv2.  Please make sure that this change in licensing makes its
-+   way upstream.  -russ
-+   -- quote from email
-+**/
-+
- /* cs89x0.c: A Crystal Semiconductor CS89[02]0 driver for etherboot. */
- /*
-   Permission is granted to distribute the enclosed cs89x0.[ch] driver
-diff -Nur grub-0.97/netboot/cs89x0.h grub-0.97-patched/netboot/cs89x0.h
---- grub-0.97/netboot/cs89x0.h 2003-07-09 13:45:37.000000000 +0200
-+++ grub-0.97-patched/netboot/cs89x0.h 2012-11-11 17:07:12.723729469 +0100
-@@ -1,3 +1,21 @@
-+/**
-+   Per an email message from Russ Nelson <nelson@crynwr.com> on
-+   18 March 2008 this file is now licensed under GPL Version 2.
-+
-+   From: Russ Nelson <nelson@crynwr.com>
-+   Date: Tue, 18 Mar 2008 12:42:00 -0400
-+   Subject: Re: [Etherboot-developers] cs89x0 driver in etherboot
-+   -- quote from email
-+   As copyright holder, if I say it doesn't conflict with the GPL,
-+   then it doesn't conflict with the GPL.
-+
-+   However, there's no point in causing people's brains to overheat,
-+   so yes, I grant permission for the code to be relicensed under the
-+   GPLv2.  Please make sure that this change in licensing makes its
-+   way upstream.  -russ
-+   -- quote from email
-+**/
-+
- /*  Copyright, 1988-1992, Russell Nelson, Crynwr Software
-    This program is free software; you can redistribute it and/or modify
-diff -Nur grub-0.97/netboot/etherboot.h grub-0.97-patched/netboot/etherboot.h
---- grub-0.97/netboot/etherboot.h      2003-07-09 13:45:37.000000000 +0200
-+++ grub-0.97-patched/netboot/etherboot.h      2012-11-11 17:07:12.723729469 +0100
-@@ -531,9 +531,6 @@
- extern int network_ready;
- extern struct rom_info rom;
- extern struct arptable_t arptable[MAX_ARP];
--extern struct bootpd_t bootp_data;
--#define       BOOTP_DATA_ADDR (&bootp_data)
--extern unsigned char *end_of_rfc1533;
- /* config.c */
- extern struct nic nic;
-diff -Nur grub-0.97/netboot/main.c grub-0.97-patched/netboot/main.c
---- grub-0.97/netboot/main.c   2004-05-21 00:19:33.000000000 +0200
-+++ grub-0.97-patched/netboot/main.c   2012-11-11 17:07:12.724729500 +0100
-@@ -56,7 +56,8 @@
- static unsigned long netmask;
- static struct bootpd_t bootp_data;
- static unsigned long xid;
--static unsigned char *end_of_rfc1533 = NULL;
-+
-+#define       BOOTP_DATA_ADDR (&bootp_data)
- #ifndef       NO_DHCP_SUPPORT
- #endif /* NO_DHCP_SUPPORT */
-@@ -83,7 +84,9 @@
-   RFC2132_MAX_SIZE,2, /* request as much as we can */
-   ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
-   RFC2132_PARAM_LIST, 4, RFC1533_NETMASK, RFC1533_GATEWAY,
--  RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH
-+  RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
-+  /* Vendor class identifier */
-+  RFC2132_VENDOR_CLASS_ID, 10, 'G', 'R', 'U', 'B', 'C', 'l', 'i', 'e', 'n', 't',
- };
- static const unsigned char dhcprequest[] =
-@@ -103,6 +106,8 @@
-   /* Etherboot vendortags */
-   RFC1533_VENDOR_MAGIC,
-   RFC1533_VENDOR_CONFIGFILE,
-+  /* Vendor class identifier */
-+  RFC2132_VENDOR_CLASS_ID, 10, 'G', 'R', 'U', 'B', 'C', 'l', 'i', 'e', 'n', 't',
- };
- #endif /* ! NO_DHCP_SUPPORT */
-@@ -701,7 +706,7 @@
-      "adcw %%ax,%0\n\t"               /* add carry of previous iteration */
-      "loop 1b\n\t"
-      "adcw $0,%0"             /* add carry of last iteration */
--     : "=b" (*sum), "=S"(start), "=c"(len)
-+     : "=r" (*sum), "=S"(start), "=c"(len)
-      : "0"(*sum), "1"(start), "2"(len)
-      : "ax", "cc"
-      );
-@@ -967,7 +972,6 @@
-   
-   if (block == 0)
-     {
--      end_of_rfc1533 = NULL;
-       vendorext_isvalid = 0;
-       
-       if (grub_memcmp (p, rfc1533_cookie, 4))
-@@ -1021,7 +1025,7 @@
-       }
-       else if (c == RFC1533_END)
-       {
--        end_of_rfc1533 = endp = p;
-+        endp = p;
-         continue;
-       }
-       else if (c == RFC1533_NETMASK)
-diff -Nur grub-0.97/netboot/natsemi.c grub-0.97-patched/netboot/natsemi.c
---- grub-0.97/netboot/natsemi.c        2003-07-09 13:45:38.000000000 +0200
-+++ grub-0.97-patched/netboot/natsemi.c        2012-11-11 17:07:12.724729500 +0100
-@@ -608,7 +608,7 @@
-                const char  *p)     /* Packet */
- {
-     u32 status, to, nstype;
--    u32 tx_status;
-+    volatile u32 tx_status;
-     
-     /* Stop the transmitter */
-     outl(TxOff, ioaddr + ChipCmd);
-@@ -647,7 +647,7 @@
-     to = currticks() + TX_TIMEOUT;
--    while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to))
-+    while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
-         /* wait */ ;
-     if (currticks() >= to) {
-diff -Nur grub-0.97/netboot/pci.c grub-0.97-patched/netboot/pci.c
---- grub-0.97/netboot/pci.c    2003-07-09 13:45:38.000000000 +0200
-+++ grub-0.97-patched/netboot/pci.c    2012-11-11 17:07:07.227553894 +0100
-@@ -105,13 +105,16 @@
-       save_flags(flags);
-       __asm__(
-+              "pushl %%ebx\n\t" /* save %ebx */
- #ifdef ABSOLUTE_WITHOUT_ASTERISK
--              "lcall (%%edi)"
-+              "lcall (%%edi)\n\t"
- #else
--              "lcall *(%%edi)"
-+              "lcall *(%%edi)\n\t"
- #endif
-+              "movl %%ebx, %1\n\t" /* capture what was in %ebx */
-+              "popl %%ebx\n\t" /* restore %ebx */
-               : "=a" (return_code),
--                "=b" (address),
-+                "=r" (address),
-                 "=c" (length),
-                 "=d" (entry)
-               : "0" (service),
-@@ -141,18 +144,21 @@
-         save_flags(flags);
-         __asm__(
-+              "pushl %%ebx\n\t" /* save %ebx */
-+              "movl %3, %%ebx\n\t" /* put the value into ebx */
- #ifdef ABSOLUTE_WITHOUT_ASTERISK
-               "lcall (%%esi)\n\t"
- #else
-               "lcall *(%%esi)\n\t"
- #endif
-                 "jc 1f\n\t"
--                "xor %%ah, %%ah\n"
-+              "popl %%ebx\n\t" /* restore %ebx */
-+              "xor %%ah, %%ah\n\t"
-                 "1:"
-                 : "=c" (*value),
-                   "=a" (ret)
-                 : "1" (PCIBIOS_READ_CONFIG_BYTE),
--                  "b" (bx),
-+                  "r" (bx),
-                   "D" ((long) where),
-                   "S" (&pci_indirect));
-         restore_flags(flags);
-@@ -168,18 +174,21 @@
-         save_flags(flags);
-         __asm__(
-+              "pushl %%ebx\n\t" /* save %ebx */
-+              "movl %3, %%ebx\n\t" /* put the value into ebx */
- #ifdef ABSOLUTE_WITHOUT_ASTERISK
-               "lcall (%%esi)\n\t"
- #else
-               "lcall *(%%esi)\n\t"
- #endif
-                 "jc 1f\n\t"
--                "xor %%ah, %%ah\n"
-+              "popl %%ebx\n\t" /* restore %ebx */
-+              "xor %%ah, %%ah\n\t"
-                 "1:"
-                 : "=c" (*value),
-                   "=a" (ret)
-                 : "1" (PCIBIOS_READ_CONFIG_WORD),
--                  "b" (bx),
-+              "r" (bx),
-                   "D" ((long) where),
-                   "S" (&pci_indirect));
-         restore_flags(flags);
-@@ -195,18 +204,21 @@
-         save_flags(flags);
-         __asm__(
-+          "pushl %%ebx\n\t" /* save %ebx */
-+          "movl %3, %%ebx\n\t" /* put the value into ebx */
- #ifdef ABSOLUTE_WITHOUT_ASTERISK
-               "lcall (%%esi)\n\t"
- #else
-               "lcall *(%%esi)\n\t"
- #endif
-                 "jc 1f\n\t"
--                "xor %%ah, %%ah\n"
-+          "popl %%ebx\n\t" /* restore %ebx */
-+          "xor %%ah, %%ah\n\t"
-                 "1:"
-                 : "=c" (*value),
-                   "=a" (ret)
-                 : "1" (PCIBIOS_READ_CONFIG_DWORD),
--                  "b" (bx),
-+          "r" (bx),
-                   "D" ((long) where),
-                   "S" (&pci_indirect));
-         restore_flags(flags);
-@@ -222,18 +234,21 @@
-       save_flags(flags); cli();
-       __asm__(
-+          "pushl %%ebx\n\t" /* save %ebx */
-+          "movl %3, %%ebx\n\t" /* put the value into ebx */
- #ifdef ABSOLUTE_WITHOUT_ASTERISK
-               "lcall (%%esi)\n\t"
- #else
-               "lcall *(%%esi)\n\t"
- #endif
-               "jc 1f\n\t"
--              "xor %%ah, %%ah\n"
-+          "popl %%ebx\n\t" /* restore %ebx */
-+          "xor %%ah, %%ah\n\t"
-               "1:"
-               : "=a" (ret)
-               : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
-                 "c" (value),
--                "b" (bx),
-+          "r" (bx),
-                 "D" ((long) where),
-                 "S" (&pci_indirect));
-       restore_flags(flags);
-@@ -249,18 +264,21 @@
-       save_flags(flags); cli();
-       __asm__(
-+          "pushl %%ebx\n\t" /* save %ebx */
-+          "movl %3, %%ebx\n\t" /* put the value into ebx */
- #ifdef ABSOLUTE_WITHOUT_ASTERISK
-               "lcall (%%esi)\n\t"
- #else
-               "lcall *(%%esi)\n\t"
- #endif
-               "jc 1f\n\t"
--              "xor %%ah, %%ah\n"
-+          "popl %%ebx\n\t" /* restore %ebx */
-+          "xor %%ah, %%ah\n\t"
-               "1:"
-               : "=a" (ret)
-               : "0" (PCIBIOS_WRITE_CONFIG_WORD),
-                 "c" (value),
--                "b" (bx),
-+          "r" (bx),
-                 "D" ((long) where),
-                 "S" (&pci_indirect));
-       restore_flags(flags);
-@@ -276,18 +294,21 @@
-       save_flags(flags); cli();
-       __asm__(
-+          "pushl %%ebx\n\t" /* save %ebx */
-+          "movl %3, %%ebx\n\t" /* put the value into ebx */
- #ifdef ABSOLUTE_WITHOUT_ASTERISK
-               "lcall (%%esi)\n\t"
- #else
-               "lcall *(%%esi)\n\t"
- #endif
-               "jc 1f\n\t"
--              "xor %%ah, %%ah\n"
-+          "popl %%ebx\n\t" /* restore %ebx */
-+          "xor %%ah, %%ah\n\t"
-               "1:"
-               : "=a" (ret)
-               : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
-                 "c" (value),
--                "b" (bx),
-+          "r" (bx),
-                 "D" ((long) where),
-                 "S" (&pci_indirect));
-       restore_flags(flags);
-@@ -308,20 +329,22 @@
-               save_flags(flags);
-               __asm__(
-+              "pushl %%ebx\n\t" /* save %ebx */
- #ifdef ABSOLUTE_WITHOUT_ASTERISK
-                       "lcall (%%edi)\n\t"
- #else
-                       "lcall *(%%edi)\n\t"
- #endif
-                       "jc 1f\n\t"
--                      "xor %%ah, %%ah\n"
-+              "xor %%ah, %%ah\n\t"
-                       "1:\tshl $8, %%eax\n\t"
--                      "movw %%bx, %%ax"
-+              "movw %%bx, %%ax\n\t"
-+              "popl %%ebx\n\t" /* restore %ebx */
-                       : "=d" (signature),
-                         "=a" (pack)
-                       : "1" (PCIBIOS_PCI_BIOS_PRESENT),
-                         "D" (&pci_indirect)
--                      : "bx", "cx");
-+              : "cx");
-               restore_flags(flags);
-               present_status = (pack >> 16) & 0xff;
-diff -Nur grub-0.97/netboot/sis900.c grub-0.97-patched/netboot/sis900.c
---- grub-0.97/netboot/sis900.c 2003-07-09 13:45:38.000000000 +0200
-+++ grub-0.97-patched/netboot/sis900.c 2012-11-11 17:07:12.725729531 +0100
-@@ -901,7 +901,7 @@
-                 const char  *p)     /* Packet */
- {
-     u32 status, to, nstype;
--    u32 tx_status;
-+    volatile u32 tx_status;
-     
-     /* Stop the transmitter */
-     outl(TxDIS, ioaddr + cr);
-@@ -940,7 +940,7 @@
-     to = currticks() + TX_TIMEOUT;
--    while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to))
-+    while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
-         /* wait */ ;
-     if (currticks() >= to) {
-diff -Nur grub-0.97/stage1/Makefile.am grub-0.97-patched/stage1/Makefile.am
---- grub-0.97/stage1/Makefile.am       2004-07-16 13:44:56.000000000 +0200
-+++ grub-0.97-patched/stage1/Makefile.am       2012-11-11 17:07:12.747730236 +0100
-@@ -1,11 +1,11 @@
--pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
--nodist_pkglib_DATA = stage1
-+stagedir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
-+nodist_stage_DATA = stage1
--CLEANFILES = $(nodist_pkglib_DATA)
-+CLEANFILES = $(nodist_stage_DATA)
- # We can't use builtins or standard includes.
- AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
--LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
-+stage1_exec_LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
- noinst_PROGRAMS = stage1.exec
- stage1_exec_SOURCES = stage1.S stage1.h
-diff -Nur grub-0.97/stage2/asm.S grub-0.97-patched/stage2/asm.S
---- grub-0.97/stage2/asm.S     2004-06-19 18:55:22.000000000 +0200
-+++ grub-0.97-patched/stage2/asm.S     2012-11-11 17:07:03.850446017 +0100
-@@ -1651,7 +1651,29 @@
-       jnz     3f
-       ret
--3:    /* use keyboard controller */
-+3:    /*
-+       * try to switch gateA20 using PORT92, the "Fast A20 and Init"
-+       * register
-+      */
-+      mov $0x92, %dx
-+      inb %dx, %al
-+      /* skip the port92 code if it's unimplemented (read returns 0xff) */
-+      cmpb $0xff, %al
-+      jz 6f
-+      
-+      /* set or clear bit1, the ALT_A20_GATE bit */
-+      movb 4(%esp), %ah
-+      testb %ah, %ah
-+      jz 4f
-+      orb $2, %al
-+      jmp 5f
-+4:    and $0xfd, %al
-+      
-+      /* clear the INIT_NOW bit don't accidently reset the machine */
-+5:    and $0xfe, %al
-+      outb %al, %dx
-+      
-+6:    /* use keyboard controller */
-       pushl   %eax
-       call    gloop1
-@@ -1661,9 +1683,12 @@
- gloopint1:
-       inb     $K_STATUS
-+      cmpb    $0xff, %al
-+      jz      gloopint1_done
-       andb    $K_IBUF_FUL, %al
-       jnz     gloopint1
-+gloopint1_done:       
-       movb    $KB_OUTPUT_MASK, %al
-       cmpb    $0, 0x8(%esp)
-       jz      gdoit
-@@ -1684,6 +1709,8 @@
- gloop1:
-       inb     $K_STATUS
-+      cmpb    $0xff, %al
-+      jz      gloop2ret
-       andb    $K_IBUF_FUL, %al
-       jnz     gloop1
-@@ -1991,6 +2018,11 @@
- ENTRY(console_getkey)
-       push    %ebp
-+wait_for_key:
-+      call    EXT_C(console_checkkey)
-+      incl    %eax
-+      jz      wait_for_key
-+      
-       call    EXT_C(prot_to_real)
-       .code16
-@@ -2216,6 +2248,156 @@
-       pop     %ebx
-       pop     %ebp
-       ret
-+
-+/* graphics mode functions */
-+#ifdef SUPPORT_GRAPHICS
-+VARIABLE(cursorX)
-+.word 0
-+VARIABLE(cursorY)
-+.word 0
-+VARIABLE(cursorCount)
-+.word 0
-+VARIABLE(cursorBuf)
-+.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-+
-+      
-+/*
-+ * int set_videomode(mode)
-+ * BIOS call "INT 10H Function 0h" to set video mode
-+ *    Call with       %ah = 0x0
-+ *                    %al = video mode
-+ *      Returns old videomode.
-+ */
-+ENTRY(set_videomode)
-+      push    %ebp
-+      push    %ebx
-+      push    %ecx
-+
-+      movb    0x10(%esp), %cl
-+
-+      call    EXT_C(prot_to_real)
-+      .code16
-+
-+      xorw    %bx, %bx
-+      movb    $0xf, %ah
-+      int     $0x10                   /* Get Current Video mode */
-+      movb    %al, %ch
-+      xorb    %ah, %ah
-+      movb    %cl, %al
-+        int   $0x10                   /* Set Video mode */
-+
-+      DATA32  call    EXT_C(real_to_prot)
-+      .code32
-+
-+      xorb    %ah, %ah
-+      movb    %ch, %al
-+
-+      pop     %ecx
-+      pop     %ebx
-+      pop     %ebp
-+      ret
-+
-+
-+/*
-+ * unsigned char * graphics_get_font()
-+ * BIOS call "INT 10H Function 11h" to set font
-+ *      Call with       %ah = 0x11
-+ */
-+ENTRY(graphics_get_font)
-+      push    %ebp
-+      push    %ebx
-+      push    %ecx
-+      push    %edx
-+
-+      call    EXT_C(prot_to_real)
-+      .code16
-+
-+      movw    $0x1130, %ax
-+      movb    $6, %bh         /* font 8x16 */
-+      int     $0x10
-+      movw    %bp, %dx
-+      movw    %es, %cx
-+
-+      DATA32  call    EXT_C(real_to_prot)
-+      .code32
-+
-+      xorl    %eax, %eax
-+      movw    %cx, %ax
-+      shll    $4, %eax
-+      movw    %dx, %ax
-+
-+      pop     %edx
-+      pop     %ecx
-+      pop     %ebx
-+      pop     %ebp
-+      ret
-+      
-+
-+      
-+/*
-+ * graphics_set_palette(index, red, green, blue)
-+ * BIOS call "INT 10H Function 10h" to set individual dac register
-+ *    Call with       %ah = 0x10
-+ *                    %bx = register number
-+ *                    %ch = new value for green (0-63)
-+ *                    %cl = new value for blue (0-63)
-+ *                    %dh = new value for red (0-63)
-+ */
-+
-+ENTRY(graphics_set_palette)
-+      push    %ebp
-+      push    %eax
-+      push    %ebx
-+      push    %ecx
-+      push    %edx
-+
-+      movw    $0x3c8, %bx             /* address write mode register */
-+
-+      /* wait vertical retrace */
-+
-+      movw    $0x3da, %dx
-+l1b:  inb     %dx, %al        /* wait vertical active display */
-+      test    $8, %al
-+      jnz     l1b
-+
-+l2b:  inb     %dx, %al        /* wait vertical retrace */
-+      test    $8, %al
-+      jnz     l2b
-+
-+      mov     %bx, %dx
-+      movb    0x18(%esp), %al         /* index */
-+      outb    %al, %dx
-+      inc     %dx
-+
-+      movb    0x1c(%esp), %al         /* red */
-+      outb    %al, %dx
-+
-+      movb    0x20(%esp), %al         /* green */
-+      outb    %al, %dx
-+
-+      movb    0x24(%esp), %al         /* blue */
-+      outb    %al, %dx
-+
-+      movw    0x18(%esp), %bx
-+
-+      call    EXT_C(prot_to_real)
-+      .code16
-+
-+      movb    %bl, %bh
-+      movw    $0x1000, %ax
-+      int     $0x10
-+
-+      DATA32  call    EXT_C(real_to_prot)
-+      .code32 
-+
-+      pop     %edx
-+      pop     %ecx
-+      pop     %ebx
-+      pop     %eax
-+      pop     %ebp
-+      ret
-+
-+#endif /* SUPPORT_GRAPHICS */
-               
- /*
-  * getrtsecs()
-diff -Nur grub-0.97/stage2/bios.c grub-0.97-patched/stage2/bios.c
---- grub-0.97/stage2/bios.c    2004-03-27 17:34:04.000000000 +0100
-+++ grub-0.97-patched/stage2/bios.c    2012-11-11 17:07:12.751730363 +0100
-@@ -47,7 +47,7 @@
-    return the error number. Otherwise, return 0.  */
- int
- biosdisk (int read, int drive, struct geometry *geometry,
--        int sector, int nsec, int segment)
-+        unsigned int sector, int nsec, int segment)
- {
-   int err;
-   
-@@ -60,7 +60,18 @@
-       unsigned short blocks;
-       unsigned long buffer;
-       unsigned long long block;
--      } __attribute__ ((packed)) dap;
-+
-+      /* This structure is passed in the stack. A buggy BIOS could write
-+       * garbage data to the tail of the struct and hang the machine. So
-+       * we need this protection. - Tinybit
-+       */
-+      unsigned char dummy[16];
-+      } __attribute__ ((packed)) *dap;
-+
-+      /* Even the above protection is not enough to avoid stupid actions by
-+       * buggy BIOSes. So we do it in the 0040:0000 segment. - Tinybit
-+       */
-+      dap = (struct disk_address_packet *)0x580;
-       /* XXX: Don't check the geometry by default, because some buggy
-        BIOSes don't return the number of total sectors correctly,
-@@ -72,15 +83,15 @@
-       /* FIXME: sizeof (DAP) must be 0x10. Should assert that the compiler
-        can't add any padding.  */
--      dap.length = sizeof (dap);
--      dap.block = sector;
--      dap.blocks = nsec;
--      dap.reserved = 0;
-+      dap->length = 0x10;
-+      dap->block = sector;
-+      dap->blocks = nsec;
-+      dap->reserved = 0;
-       /* This is undocumented part. The address is formated in
-        SEGMENT:ADDRESS.  */
--      dap.buffer = segment << 16;
-+      dap->buffer = segment << 16;
-       
--      err = biosdisk_int13_extensions ((read + 0x42) << 8, drive, &dap);
-+      err = biosdisk_int13_extensions ((read + 0x42) << 8, drive, dap);
- /* #undef NO_INT13_FALLBACK */
- #ifndef NO_INT13_FALLBACK
-diff -Nur grub-0.97/stage2/boot.c grub-0.97-patched/stage2/boot.c
---- grub-0.97/stage2/boot.c    2004-03-30 13:44:08.000000000 +0200
-+++ grub-0.97-patched/stage2/boot.c    2012-11-11 17:07:12.727729596 +0100
-@@ -1,7 +1,7 @@
- /* boot.c - load and bootstrap a kernel */
- /*
-  *  GRUB  --  GRand Unified Bootloader
-- *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
-+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005  Free Software Foundation, Inc.
-  *
-  *  This program is free software; you can redistribute it and/or modify
-  *  it under the terms of the GNU General Public License as published by
-@@ -96,7 +96,7 @@
-   lh = (struct linux_kernel_header *) buffer;
-   
-   /* ELF loading supported if multiboot, FreeBSD and NetBSD.  */
--  if ((type == KERNEL_TYPE_MULTIBOOT
-+  if (((type == KERNEL_TYPE_MULTIBOOT && ! (flags & MULTIBOOT_AOUT_KLUDGE))
-        || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD
-        || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0
-        || suggested_type == KERNEL_TYPE_NETBSD)
-@@ -241,7 +241,7 @@
-           }
-         if (lh->version >= 0x0202)
--          lh->cmd_line_ptr = linux_data_real_addr + LINUX_CL_OFFSET;
-+          lh->cmd_line_ptr = linux_data_real_addr + LINUX_CL_0202_PRM_OFFSET;
-         else
-           {
-             lh->cl_magic = LINUX_CL_MAGIC;
-@@ -407,6 +407,15 @@
-           while (dest < linux_data_tmp_addr + LINUX_CL_END_OFFSET && *src)
-             *(dest++) = *(src++);
-       
-+          {
-+          char *src = skip_to (0, arg);
-+          char *dest = linux_data_tmp_addr + LINUX_CL_0202_PRM_OFFSET;
-+      
-+          while (dest < linux_data_tmp_addr + LINUX_CL_0202_PRM_END_OFFSET && *src)
-+            *(dest++) = *(src++);
-+          *dest = 0;
-+          }
-+
-           /* Old Linux kernels have problems determining the amount of
-              the available memory.  To work around this problem, we add
-              the "mem" option to the kernel command line.  This has its
-@@ -824,8 +833,11 @@
-     moveto = (mbi.mem_upper + 0x400) << 10;
-   
-   moveto = (moveto - len) & 0xfffff000;
--  max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203
--            ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);
-+  max_addr = LINUX_INITRD_MAX_ADDRESS;
-+  if (lh->header == LINUX_MAGIC_SIGNATURE &&
-+      lh->version >= 0x0203 &&
-+      lh->initrd_addr_max < max_addr)
-+    max_addr = lh->initrd_addr_max;
-   if (moveto + len >= max_addr)
-     moveto = (max_addr - len) & 0xfffff000;
-   
-diff -Nur grub-0.97/stage2/boot.c.orig grub-0.97-patched/stage2/boot.c.orig
---- grub-0.97/stage2/boot.c.orig       1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/stage2/boot.c.orig       2004-03-30 13:44:08.000000000 +0200
-@@ -0,0 +1,1020 @@
-+/* boot.c - load and bootstrap a kernel */
-+/*
-+ *  GRUB  --  GRand Unified Bootloader
-+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+
-+#include "shared.h"
-+
-+#include "freebsd.h"
-+#include "imgact_aout.h"
-+#include "i386-elf.h"
-+
-+static int cur_addr;
-+entry_func entry_addr;
-+static struct mod_list mll[99];
-+static int linux_mem_size;
-+
-+/*
-+ *  The next two functions, 'load_image' and 'load_module', are the building
-+ *  blocks of the multiboot loader component.  They handle essentially all
-+ *  of the gory details of loading in a bootable image and the modules.
-+ */
-+
-+kernel_t
-+load_image (char *kernel, char *arg, kernel_t suggested_type,
-+          unsigned long load_flags)
-+{
-+  int len, i, exec_type = 0, align_4k = 1;
-+  entry_func real_entry_addr = 0;
-+  kernel_t type = KERNEL_TYPE_NONE;
-+  unsigned long flags = 0, text_len = 0, data_len = 0, bss_len = 0;
-+  char *str = 0, *str2 = 0;
-+  struct linux_kernel_header *lh;
-+  union
-+    {
-+      struct multiboot_header *mb;
-+      struct exec *aout;
-+      Elf32_Ehdr *elf;
-+    }
-+  pu;
-+  /* presuming that MULTIBOOT_SEARCH is large enough to encompass an
-+     executable header */
-+  unsigned char buffer[MULTIBOOT_SEARCH];
-+
-+  /* sets the header pointer to point to the beginning of the
-+     buffer by default */
-+  pu.aout = (struct exec *) buffer;
-+
-+  if (!grub_open (kernel))
-+    return KERNEL_TYPE_NONE;
-+
-+  if (!(len = grub_read (buffer, MULTIBOOT_SEARCH)) || len < 32)
-+    {
-+      grub_close ();
-+      
-+      if (!errnum)
-+      errnum = ERR_EXEC_FORMAT;
-+
-+      return KERNEL_TYPE_NONE;
-+    }
-+
-+  for (i = 0; i < len; i++)
-+    {
-+      if (MULTIBOOT_FOUND ((int) (buffer + i), len - i))
-+      {
-+        flags = ((struct multiboot_header *) (buffer + i))->flags;
-+        if (flags & MULTIBOOT_UNSUPPORTED)
-+          {
-+            grub_close ();
-+            errnum = ERR_BOOT_FEATURES;
-+            return KERNEL_TYPE_NONE;
-+          }
-+        type = KERNEL_TYPE_MULTIBOOT;
-+        str2 = "Multiboot";
-+        break;
-+      }
-+    }
-+
-+  /* Use BUFFER as a linux kernel header, if the image is Linux zImage
-+     or bzImage.  */
-+  lh = (struct linux_kernel_header *) buffer;
-+  
-+  /* ELF loading supported if multiboot, FreeBSD and NetBSD.  */
-+  if ((type == KERNEL_TYPE_MULTIBOOT
-+       || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD
-+       || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0
-+       || suggested_type == KERNEL_TYPE_NETBSD)
-+      && len > sizeof (Elf32_Ehdr)
-+      && BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer))))
-+    {
-+      if (type == KERNEL_TYPE_MULTIBOOT)
-+      entry_addr = (entry_func) pu.elf->e_entry;
-+      else
-+      entry_addr = (entry_func) (pu.elf->e_entry & 0xFFFFFF);
-+
-+      if (entry_addr < (entry_func) 0x100000)
-+      errnum = ERR_BELOW_1MB;
-+
-+      /* don't want to deal with ELF program header at some random
-+         place in the file -- this generally won't happen */
-+      if (pu.elf->e_phoff == 0 || pu.elf->e_phnum == 0
-+        || ((pu.elf->e_phoff + (pu.elf->e_phentsize * pu.elf->e_phnum))
-+            >= len))
-+      errnum = ERR_EXEC_FORMAT;
-+      str = "elf";
-+
-+      if (type == KERNEL_TYPE_NONE)
-+      {
-+        /* At the moment, there is no way to identify a NetBSD ELF
-+           kernel, so rely on the suggested type by the user.  */
-+        if (suggested_type == KERNEL_TYPE_NETBSD)
-+          {
-+            str2 = "NetBSD";
-+            type = suggested_type;
-+          }
-+        else
-+          {
-+            str2 = "FreeBSD";
-+            type = KERNEL_TYPE_FREEBSD;
-+          }
-+      }
-+    }
-+  else if (flags & MULTIBOOT_AOUT_KLUDGE)
-+    {
-+      pu.mb = (struct multiboot_header *) (buffer + i);
-+      entry_addr = (entry_func) pu.mb->entry_addr;
-+      cur_addr = pu.mb->load_addr;
-+      /* first offset into file */
-+      grub_seek (i - (pu.mb->header_addr - cur_addr));
-+
-+      /* If the load end address is zero, load the whole contents.  */
-+      if (! pu.mb->load_end_addr)
-+      pu.mb->load_end_addr = cur_addr + filemax;
-+      
-+      text_len = pu.mb->load_end_addr - cur_addr;
-+      data_len = 0;
-+
-+      /* If the bss end address is zero, assume that there is no bss area.  */
-+      if (! pu.mb->bss_end_addr)
-+      pu.mb->bss_end_addr = pu.mb->load_end_addr;
-+      
-+      bss_len = pu.mb->bss_end_addr - pu.mb->load_end_addr;
-+
-+      if (pu.mb->header_addr < pu.mb->load_addr
-+        || pu.mb->load_end_addr <= pu.mb->load_addr
-+        || pu.mb->bss_end_addr < pu.mb->load_end_addr
-+        || (pu.mb->header_addr - pu.mb->load_addr) > i)
-+      errnum = ERR_EXEC_FORMAT;
-+
-+      if (cur_addr < 0x100000)
-+      errnum = ERR_BELOW_1MB;
-+
-+      pu.aout = (struct exec *) buffer;
-+      exec_type = 2;
-+      str = "kludge";
-+    }
-+  else if (len > sizeof (struct exec) && !N_BADMAG ((*(pu.aout))))
-+    {
-+      entry_addr = (entry_func) pu.aout->a_entry;
-+
-+      if (type == KERNEL_TYPE_NONE)
-+      {
-+        /*
-+         *  If it doesn't have a Multiboot header, then presume
-+         *  it is either a FreeBSD or NetBSD executable.  If so,
-+         *  then use a magic number of normal ordering, ZMAGIC to
-+         *  determine if it is FreeBSD.
-+         *
-+         *  This is all because freebsd and netbsd seem to require
-+         *  masking out some address bits...  differently for each
-+         *  one...  plus of course we need to know which booting
-+         *  method to use.
-+         */
-+        entry_addr = (entry_func) ((int) entry_addr & 0xFFFFFF);
-+        
-+        if (buffer[0] == 0xb && buffer[1] == 1)
-+          {
-+            type = KERNEL_TYPE_FREEBSD;
-+            cur_addr = (int) entry_addr;
-+            str2 = "FreeBSD";
-+          }
-+        else
-+          {
-+            type = KERNEL_TYPE_NETBSD;
-+            cur_addr = (int) entry_addr & 0xF00000;
-+            if (N_GETMAGIC ((*(pu.aout))) != NMAGIC)
-+              align_4k = 0;
-+            str2 = "NetBSD";
-+          }
-+      }
-+
-+      /* first offset into file */
-+      grub_seek (N_TXTOFF (*(pu.aout)));
-+      text_len = pu.aout->a_text;
-+      data_len = pu.aout->a_data;
-+      bss_len = pu.aout->a_bss;
-+
-+      if (cur_addr < 0x100000)
-+      errnum = ERR_BELOW_1MB;
-+
-+      exec_type = 1;
-+      str = "a.out";
-+    }
-+  else if (lh->boot_flag == BOOTSEC_SIGNATURE
-+         && lh->setup_sects <= LINUX_MAX_SETUP_SECTS)
-+    {
-+      int big_linux = 0;
-+      int setup_sects = lh->setup_sects;
-+
-+      if (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0200)
-+      {
-+        big_linux = (lh->loadflags & LINUX_FLAG_BIG_KERNEL);
-+        lh->type_of_loader = LINUX_BOOT_LOADER_TYPE;
-+
-+        /* Put the real mode part at as a high location as possible.  */
-+        linux_data_real_addr
-+          = (char *) ((mbi.mem_lower << 10) - LINUX_SETUP_MOVE_SIZE);
-+        /* But it must not exceed the traditional area.  */
-+        if (linux_data_real_addr > (char *) LINUX_OLD_REAL_MODE_ADDR)
-+          linux_data_real_addr = (char *) LINUX_OLD_REAL_MODE_ADDR;
-+
-+        if (lh->version >= 0x0201)
-+          {
-+            lh->heap_end_ptr = LINUX_HEAP_END_OFFSET;
-+            lh->loadflags |= LINUX_FLAG_CAN_USE_HEAP;
-+          }
-+
-+        if (lh->version >= 0x0202)
-+          lh->cmd_line_ptr = linux_data_real_addr + LINUX_CL_OFFSET;
-+        else
-+          {
-+            lh->cl_magic = LINUX_CL_MAGIC;
-+            lh->cl_offset = LINUX_CL_OFFSET;
-+            lh->setup_move_size = LINUX_SETUP_MOVE_SIZE;
-+          }
-+      }
-+      else
-+      {
-+        /* Your kernel is quite old...  */
-+        lh->cl_magic = LINUX_CL_MAGIC;
-+        lh->cl_offset = LINUX_CL_OFFSET;
-+        
-+        setup_sects = LINUX_DEFAULT_SETUP_SECTS;
-+
-+        linux_data_real_addr = (char *) LINUX_OLD_REAL_MODE_ADDR;
-+      }
-+      
-+      /* If SETUP_SECTS is not set, set it to the default (4).  */
-+      if (! setup_sects)
-+      setup_sects = LINUX_DEFAULT_SETUP_SECTS;
-+
-+      data_len = setup_sects << 9;
-+      text_len = filemax - data_len - SECTOR_SIZE;
-+
-+      linux_data_tmp_addr = (char *) LINUX_BZIMAGE_ADDR + text_len;
-+      
-+      if (! big_linux
-+        && text_len > linux_data_real_addr - (char *) LINUX_ZIMAGE_ADDR)
-+      {
-+        grub_printf (" linux 'zImage' kernel too big, try 'make bzImage'\n");
-+        errnum = ERR_WONT_FIT;
-+      }
-+      else if (linux_data_real_addr + LINUX_SETUP_MOVE_SIZE
-+             > RAW_ADDR ((char *) (mbi.mem_lower << 10)))
-+      errnum = ERR_WONT_FIT;
-+      else
-+      {
-+        grub_printf ("   [Linux-%s, setup=0x%x, size=0x%x]\n",
-+                     (big_linux ? "bzImage" : "zImage"), data_len, text_len);
-+
-+        /* Video mode selection support. What a mess!  */
-+        /* NOTE: Even the word "mess" is not still enough to
-+           represent how wrong and bad the Linux video support is,
-+           but I don't want to hear complaints from Linux fanatics
-+           any more. -okuji  */
-+        {
-+          char *vga;
-+      
-+          /* Find the substring "vga=".  */
-+          vga = grub_strstr (arg, "vga=");
-+          if (vga)
-+            {
-+              char *value = vga + 4;
-+              int vid_mode;
-+          
-+              /* Handle special strings.  */
-+              if (substring ("normal", value) < 1)
-+                vid_mode = LINUX_VID_MODE_NORMAL;
-+              else if (substring ("ext", value) < 1)
-+                vid_mode = LINUX_VID_MODE_EXTENDED;
-+              else if (substring ("ask", value) < 1)
-+                vid_mode = LINUX_VID_MODE_ASK;
-+              else if (safe_parse_maxint (&value, &vid_mode))
-+                ;
-+              else
-+                {
-+                  /* ERRNUM is already set inside the function
-+                     safe_parse_maxint.  */
-+                  grub_close ();
-+                  return KERNEL_TYPE_NONE;
-+                }
-+          
-+              lh->vid_mode = vid_mode;
-+            }
-+        }
-+
-+        /* Check the mem= option to limit memory used for initrd.  */
-+        {
-+          char *mem;
-+      
-+          mem = grub_strstr (arg, "mem=");
-+          if (mem)
-+            {
-+              char *value = mem + 4;
-+          
-+              safe_parse_maxint (&value, &linux_mem_size);
-+              switch (errnum)
-+                {
-+                case ERR_NUMBER_OVERFLOW:
-+                  /* If an overflow occurs, use the maximum address for
-+                     initrd instead. This is good, because MAXINT is
-+                     greater than LINUX_INITRD_MAX_ADDRESS.  */
-+                  linux_mem_size = LINUX_INITRD_MAX_ADDRESS;
-+                  errnum = ERR_NONE;
-+                  break;
-+              
-+                case ERR_NONE:
-+                  {
-+                    int shift = 0;
-+                
-+                    switch (grub_tolower (*value))
-+                      {
-+                      case 'g':
-+                        shift += 10;
-+                      case 'm':
-+                        shift += 10;
-+                      case 'k':
-+                        shift += 10;
-+                      default:
-+                        break;
-+                      }
-+                
-+                    /* Check an overflow.  */
-+                    if (linux_mem_size > (MAXINT >> shift))
-+                      linux_mem_size = LINUX_INITRD_MAX_ADDRESS;
-+                    else
-+                      linux_mem_size <<= shift;
-+                  }
-+                  break;
-+              
-+                default:
-+                  linux_mem_size = 0;
-+                  errnum = ERR_NONE;
-+                  break;
-+                }
-+            }
-+          else
-+            linux_mem_size = 0;
-+        }
-+      
-+        /* It is possible that DATA_LEN + SECTOR_SIZE is greater than
-+           MULTIBOOT_SEARCH, so the data may have been read partially.  */
-+        if (data_len + SECTOR_SIZE <= MULTIBOOT_SEARCH)
-+          grub_memmove (linux_data_tmp_addr, buffer,
-+                        data_len + SECTOR_SIZE);
-+        else
-+          {
-+            grub_memmove (linux_data_tmp_addr, buffer, MULTIBOOT_SEARCH);
-+            grub_read (linux_data_tmp_addr + MULTIBOOT_SEARCH,
-+                       data_len + SECTOR_SIZE - MULTIBOOT_SEARCH);
-+          }
-+        
-+        if (lh->header != LINUX_MAGIC_SIGNATURE ||
-+            lh->version < 0x0200)
-+          /* Clear the heap space.  */
-+          grub_memset (linux_data_tmp_addr + ((setup_sects + 1) << 9),
-+                       0,
-+                       (64 - setup_sects - 1) << 9);
-+      
-+        /* Copy command-line plus memory hack to staging area.
-+           NOTE: Linux has a bug that it doesn't handle multiple spaces
-+           between two options and a space after a "mem=" option isn't
-+           removed correctly so the arguments to init could be like
-+           {"init", "", "", NULL}. This affects some not-very-clever
-+           shells. Thus, the code below does a trick to avoid the bug.
-+           That is, copy "mem=XXX" to the end of the command-line, and
-+           avoid to copy spaces unnecessarily. Hell.  */
-+        {
-+          char *src = skip_to (0, arg);
-+          char *dest = linux_data_tmp_addr + LINUX_CL_OFFSET;
-+      
-+          while (dest < linux_data_tmp_addr + LINUX_CL_END_OFFSET && *src)
-+            *(dest++) = *(src++);
-+      
-+          /* Old Linux kernels have problems determining the amount of
-+             the available memory.  To work around this problem, we add
-+             the "mem" option to the kernel command line.  This has its
-+             own drawbacks because newer kernels can determine the
-+             memory map more accurately.  Boot protocol 2.03, which
-+             appeared in Linux 2.4.18, provides a pointer to the kernel
-+             version string, so we could check it.  But since kernel
-+             2.4.18 and newer are known to detect memory reliably, boot
-+             protocol 2.03 already implies that the kernel is new
-+             enough.  The "mem" option is added if neither of the
-+             following conditions is met:
-+             1) The "mem" option is already present.
-+             2) The "kernel" command is used with "--no-mem-option".
-+             3) GNU GRUB is configured not to pass the "mem" option.
-+             4) The kernel supports boot protocol 2.03 or newer.  */
-+          if (! grub_strstr (arg, "mem=")
-+              && ! (load_flags & KERNEL_LOAD_NO_MEM_OPTION)
-+              && lh->version < 0x0203         /* kernel version < 2.4.18 */
-+              && dest + 15 < linux_data_tmp_addr + LINUX_CL_END_OFFSET)
-+            {
-+              *dest++ = ' ';
-+              *dest++ = 'm';
-+              *dest++ = 'e';
-+              *dest++ = 'm';
-+              *dest++ = '=';
-+          
-+              dest = convert_to_ascii (dest, 'u', (extended_memory + 0x400));
-+              *dest++ = 'K';
-+            }
-+      
-+          *dest = 0;
-+        }
-+      
-+        /* offset into file */
-+        grub_seek (data_len + SECTOR_SIZE);
-+      
-+        cur_addr = (int) linux_data_tmp_addr + LINUX_SETUP_MOVE_SIZE;
-+        grub_read ((char *) LINUX_BZIMAGE_ADDR, text_len);
-+      
-+        if (errnum == ERR_NONE)
-+          {
-+            grub_close ();
-+        
-+            /* Sanity check.  */
-+            if (suggested_type != KERNEL_TYPE_NONE
-+                && ((big_linux && suggested_type != KERNEL_TYPE_BIG_LINUX)
-+                    || (! big_linux && suggested_type != KERNEL_TYPE_LINUX)))
-+              {
-+                errnum = ERR_EXEC_FORMAT;
-+                return KERNEL_TYPE_NONE;
-+              }
-+        
-+            /* Ugly hack.  */
-+            linux_text_len = text_len;
-+        
-+            return big_linux ? KERNEL_TYPE_BIG_LINUX : KERNEL_TYPE_LINUX;
-+          }
-+      }
-+    }
-+  else                                /* no recognizable format */
-+    errnum = ERR_EXEC_FORMAT;
-+
-+  /* return if error */
-+  if (errnum)
-+    {
-+      grub_close ();
-+      return KERNEL_TYPE_NONE;
-+    }
-+
-+  /* fill the multiboot info structure */
-+  mbi.cmdline = (int) arg;
-+  mbi.mods_count = 0;
-+  mbi.mods_addr = 0;
-+  mbi.boot_device = (current_drive << 24) | current_partition;
-+  mbi.flags &= ~(MB_INFO_MODS | MB_INFO_AOUT_SYMS | MB_INFO_ELF_SHDR);
-+  mbi.syms.a.tabsize = 0;
-+  mbi.syms.a.strsize = 0;
-+  mbi.syms.a.addr = 0;
-+  mbi.syms.a.pad = 0;
-+
-+  printf ("   [%s-%s", str2, str);
-+
-+  str = "";
-+
-+  if (exec_type)              /* can be loaded like a.out */
-+    {
-+      if (flags & MULTIBOOT_AOUT_KLUDGE)
-+      str = "-and-data";
-+
-+      printf (", loadaddr=0x%x, text%s=0x%x", cur_addr, str, text_len);
-+
-+      /* read text, then read data */
-+      if (grub_read ((char *) RAW_ADDR (cur_addr), text_len) == text_len)
-+      {
-+        cur_addr += text_len;
-+
-+        if (!(flags & MULTIBOOT_AOUT_KLUDGE))
-+          {
-+            /* we have to align to a 4K boundary */
-+            if (align_4k)
-+              cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
-+            else
-+              printf (", C");
-+
-+            printf (", data=0x%x", data_len);
-+
-+            if ((grub_read ((char *) RAW_ADDR (cur_addr), data_len)
-+                 != data_len)
-+                && !errnum)
-+              errnum = ERR_EXEC_FORMAT;
-+            cur_addr += data_len;
-+          }
-+
-+        if (!errnum)
-+          {
-+            memset ((char *) RAW_ADDR (cur_addr), 0, bss_len);
-+            cur_addr += bss_len;
-+
-+            printf (", bss=0x%x", bss_len);
-+          }
-+      }
-+      else if (!errnum)
-+      errnum = ERR_EXEC_FORMAT;
-+
-+      if (!errnum && pu.aout->a_syms
-+        && pu.aout->a_syms < (filemax - filepos))
-+      {
-+        int symtab_err, orig_addr = cur_addr;
-+
-+        /* we should align to a 4K boundary here for good measure */
-+        if (align_4k)
-+          cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
-+
-+        mbi.syms.a.addr = cur_addr;
-+
-+        *((int *) RAW_ADDR (cur_addr)) = pu.aout->a_syms;
-+        cur_addr += sizeof (int);
-+        
-+        printf (", symtab=0x%x", pu.aout->a_syms);
-+
-+        if (grub_read ((char *) RAW_ADDR (cur_addr), pu.aout->a_syms)
-+            == pu.aout->a_syms)
-+          {
-+            cur_addr += pu.aout->a_syms;
-+            mbi.syms.a.tabsize = pu.aout->a_syms;
-+
-+            if (grub_read ((char *) &i, sizeof (int)) == sizeof (int))
-+              {
-+                *((int *) RAW_ADDR (cur_addr)) = i;
-+                cur_addr += sizeof (int);
-+
-+                mbi.syms.a.strsize = i;
-+
-+                i -= sizeof (int);
-+
-+                printf (", strtab=0x%x", i);
-+
-+                symtab_err = (grub_read ((char *) RAW_ADDR (cur_addr), i)
-+                              != i);
-+                cur_addr += i;
-+              }
-+            else
-+              symtab_err = 1;
-+          }
-+        else
-+          symtab_err = 1;
-+
-+        if (symtab_err)
-+          {
-+            printf ("(bad)");
-+            cur_addr = orig_addr;
-+            mbi.syms.a.tabsize = 0;
-+            mbi.syms.a.strsize = 0;
-+            mbi.syms.a.addr = 0;
-+          }
-+        else
-+          mbi.flags |= MB_INFO_AOUT_SYMS;
-+      }
-+    }
-+  else
-+    /* ELF executable */
-+    {
-+      unsigned loaded = 0, memaddr, memsiz, filesiz;
-+      Elf32_Phdr *phdr;
-+
-+      /* reset this to zero for now */
-+      cur_addr = 0;
-+
-+      /* scan for program segments */
-+      for (i = 0; i < pu.elf->e_phnum; i++)
-+      {
-+        phdr = (Elf32_Phdr *)
-+          (pu.elf->e_phoff + ((int) buffer)
-+           + (pu.elf->e_phentsize * i));
-+        if (phdr->p_type == PT_LOAD)
-+          {
-+            /* offset into file */
-+            grub_seek (phdr->p_offset);
-+            filesiz = phdr->p_filesz;
-+            
-+            if (type == KERNEL_TYPE_FREEBSD || type == KERNEL_TYPE_NETBSD)
-+              memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF);
-+            else
-+              memaddr = RAW_ADDR (phdr->p_paddr);
-+            
-+            memsiz = phdr->p_memsz;
-+            if (memaddr < RAW_ADDR (0x100000))
-+              errnum = ERR_BELOW_1MB;
-+
-+            /* If the memory range contains the entry address, get the
-+               physical address here.  */
-+            if (type == KERNEL_TYPE_MULTIBOOT
-+                && (unsigned) entry_addr >= phdr->p_vaddr
-+                && (unsigned) entry_addr < phdr->p_vaddr + memsiz)
-+              real_entry_addr = (entry_func) ((unsigned) entry_addr
-+                                              + memaddr - phdr->p_vaddr);
-+              
-+            /* make sure we only load what we're supposed to! */
-+            if (filesiz > memsiz)
-+              filesiz = memsiz;
-+            /* mark memory as used */
-+            if (cur_addr < memaddr + memsiz)
-+              cur_addr = memaddr + memsiz;
-+            printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz,
-+                    memsiz - filesiz);
-+            /* increment number of segments */
-+            loaded++;
-+
-+            /* load the segment */
-+            if (memcheck (memaddr, memsiz)
-+                && grub_read ((char *) memaddr, filesiz) == filesiz)
-+              {
-+                if (memsiz > filesiz)
-+                  memset ((char *) (memaddr + filesiz), 0, memsiz - filesiz);
-+              }
-+            else
-+              break;
-+          }
-+      }
-+
-+      if (! errnum)
-+      {
-+        if (! loaded)
-+          errnum = ERR_EXEC_FORMAT;
-+        else
-+          {
-+            /* Load ELF symbols.  */
-+            Elf32_Shdr *shdr = NULL;
-+            int tab_size, sec_size;
-+            int symtab_err = 0;
-+
-+            mbi.syms.e.num = pu.elf->e_shnum;
-+            mbi.syms.e.size = pu.elf->e_shentsize;
-+            mbi.syms.e.shndx = pu.elf->e_shstrndx;
-+            
-+            /* We should align to a 4K boundary here for good measure.  */
-+            if (align_4k)
-+              cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
-+            
-+            tab_size = pu.elf->e_shentsize * pu.elf->e_shnum;
-+            
-+            grub_seek (pu.elf->e_shoff);
-+            if (grub_read ((char *) RAW_ADDR (cur_addr), tab_size)
-+                == tab_size)
-+              {
-+                mbi.syms.e.addr = cur_addr;
-+                shdr = (Elf32_Shdr *) mbi.syms.e.addr;
-+                cur_addr += tab_size;
-+                
-+                printf (", shtab=0x%x", cur_addr);
-+                
-+                for (i = 0; i < mbi.syms.e.num; i++)
-+                  {
-+                    /* This section is a loaded section,
-+                       so we don't care.  */
-+                    if (shdr[i].sh_addr != 0)
-+                      continue;
-+                    
-+                    /* This section is empty, so we don't care.  */
-+                    if (shdr[i].sh_size == 0)
-+                      continue;
-+                    
-+                    /* Align the section to a sh_addralign bits boundary.  */
-+                    cur_addr = ((cur_addr + shdr[i].sh_addralign) & 
-+                                - (int) shdr[i].sh_addralign);
-+                    
-+                    grub_seek (shdr[i].sh_offset);
-+                    
-+                    sec_size = shdr[i].sh_size;
-+
-+                    if (! (memcheck (cur_addr, sec_size)
-+                           && (grub_read ((char *) RAW_ADDR (cur_addr),
-+                                          sec_size)
-+                               == sec_size)))
-+                      {
-+                        symtab_err = 1;
-+                        break;
-+                      }
-+                    
-+                    shdr[i].sh_addr = cur_addr;
-+                    cur_addr += sec_size;
-+                  }
-+              }
-+            else 
-+              symtab_err = 1;
-+            
-+            if (mbi.syms.e.addr < RAW_ADDR(0x10000))
-+              symtab_err = 1;
-+            
-+            if (symtab_err) 
-+              {
-+                printf ("(bad)");
-+                mbi.syms.e.num = 0;
-+                mbi.syms.e.size = 0;
-+                mbi.syms.e.addr = 0;
-+                mbi.syms.e.shndx = 0;
-+                cur_addr = 0;
-+              }
-+            else
-+              mbi.flags |= MB_INFO_ELF_SHDR;
-+          }
-+      }
-+    }
-+
-+  if (! errnum)
-+    {
-+      grub_printf (", entry=0x%x]\n", (unsigned) entry_addr);
-+      
-+      /* If the entry address is physically different from that of the ELF
-+       header, correct it here.  */
-+      if (real_entry_addr)
-+      entry_addr = real_entry_addr;
-+    }
-+  else
-+    {
-+      putchar ('\n');
-+      type = KERNEL_TYPE_NONE;
-+    }
-+
-+  grub_close ();
-+
-+  /* Sanity check.  */
-+  if (suggested_type != KERNEL_TYPE_NONE && suggested_type != type)
-+    {
-+      errnum = ERR_EXEC_FORMAT;
-+      return KERNEL_TYPE_NONE;
-+    }
-+  
-+  return type;
-+}
-+
-+int
-+load_module (char *module, char *arg)
-+{
-+  int len;
-+
-+  /* if we are supposed to load on 4K boundaries */
-+  cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
-+
-+  if (!grub_open (module))
-+    return 0;
-+
-+  len = grub_read ((char *) cur_addr, -1);
-+  if (! len)
-+    {
-+      grub_close ();
-+      return 0;
-+    }
-+
-+  printf ("   [Multiboot-module @ 0x%x, 0x%x bytes]\n", cur_addr, len);
-+
-+  /* these two simply need to be set if any modules are loaded at all */
-+  mbi.flags |= MB_INFO_MODS;
-+  mbi.mods_addr = (int) mll;
-+
-+  mll[mbi.mods_count].cmdline = (int) arg;
-+  mll[mbi.mods_count].mod_start = cur_addr;
-+  cur_addr += len;
-+  mll[mbi.mods_count].mod_end = cur_addr;
-+  mll[mbi.mods_count].pad = 0;
-+
-+  /* increment number of modules included */
-+  mbi.mods_count++;
-+
-+  grub_close ();
-+  return 1;
-+}
-+
-+int
-+load_initrd (char *initrd)
-+{
-+  int len;
-+  unsigned long moveto;
-+  unsigned long max_addr;
-+  struct linux_kernel_header *lh
-+    = (struct linux_kernel_header *) (cur_addr - LINUX_SETUP_MOVE_SIZE);
-+  
-+#ifndef NO_DECOMPRESSION
-+  no_decompression = 1;
-+#endif
-+  
-+  if (! grub_open (initrd))
-+    goto fail;
-+
-+  len = grub_read ((char *) cur_addr, -1);
-+  if (! len)
-+    {
-+      grub_close ();
-+      goto fail;
-+    }
-+
-+  if (linux_mem_size)
-+    moveto = linux_mem_size;
-+  else
-+    moveto = (mbi.mem_upper + 0x400) << 10;
-+  
-+  moveto = (moveto - len) & 0xfffff000;
-+  max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203
-+            ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);
-+  if (moveto + len >= max_addr)
-+    moveto = (max_addr - len) & 0xfffff000;
-+  
-+  /* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid
-+     the last page.
-+     XXX: Linux 2.2.xx has a bug in the memory range check, which is
-+     worse than that of Linux 2.3.xx, so avoid the last 64kb. *sigh*  */
-+  moveto -= 0x10000;
-+  memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
-+
-+  printf ("   [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len);
-+
-+  /* FIXME: Should check if the kernel supports INITRD.  */
-+  lh->ramdisk_image = RAW_ADDR (moveto);
-+  lh->ramdisk_size = len;
-+
-+  grub_close ();
-+
-+ fail:
-+  
-+#ifndef NO_DECOMPRESSION
-+  no_decompression = 0;
-+#endif
-+
-+  return ! errnum;
-+}
-+
-+
-+#ifdef GRUB_UTIL
-+/* Dummy function to fake the *BSD boot.  */
-+static void
-+bsd_boot_entry (int flags, int bootdev, int sym_start, int sym_end,
-+              int mem_upper, int mem_lower)
-+{
-+  stop ();
-+}
-+#endif
-+
-+
-+/*
-+ *  All "*_boot" commands depend on the images being loaded into memory
-+ *  correctly, the variables in this file being set up correctly, and
-+ *  the root partition being set in the 'saved_drive' and 'saved_partition'
-+ *  variables.
-+ */
-+
-+
-+void
-+bsd_boot (kernel_t type, int bootdev, char *arg)
-+{
-+  char *str;
-+  int clval = 0, i;
-+  struct bootinfo bi;
-+
-+#ifdef GRUB_UTIL
-+  entry_addr = (entry_func) bsd_boot_entry;
-+#else
-+  stop_floppy ();
-+#endif
-+
-+  while (*(++arg) && *arg != ' ');
-+  str = arg;
-+  while (*str)
-+    {
-+      if (*str == '-')
-+      {
-+        while (*str && *str != ' ')
-+          {
-+            if (*str == 'C')
-+              clval |= RB_CDROM;
-+            if (*str == 'a')
-+              clval |= RB_ASKNAME;
-+            if (*str == 'b')
-+              clval |= RB_HALT;
-+            if (*str == 'c')
-+              clval |= RB_CONFIG;
-+            if (*str == 'd')
-+              clval |= RB_KDB;
-+            if (*str == 'D')
-+              clval |= RB_MULTIPLE;
-+            if (*str == 'g')
-+              clval |= RB_GDB;
-+            if (*str == 'h')
-+              clval |= RB_SERIAL;
-+            if (*str == 'm')
-+              clval |= RB_MUTE;
-+            if (*str == 'r')
-+              clval |= RB_DFLTROOT;
-+            if (*str == 's')
-+              clval |= RB_SINGLE;
-+            if (*str == 'v')
-+              clval |= RB_VERBOSE;
-+            str++;
-+          }
-+        continue;
-+      }
-+      str++;
-+    }
-+
-+  if (type == KERNEL_TYPE_FREEBSD)
-+    {
-+      clval |= RB_BOOTINFO;
-+
-+      bi.bi_version = BOOTINFO_VERSION;
-+
-+      *arg = 0;
-+      while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/');
-+      if (*arg == '/')
-+      bi.bi_kernelname = arg + 1;
-+      else
-+      bi.bi_kernelname = 0;
-+
-+      bi.bi_nfs_diskless = 0;
-+      bi.bi_n_bios_used = 0;  /* this field is apparently unused */
-+
-+      for (i = 0; i < N_BIOS_GEOM; i++)
-+      {
-+        struct geometry geom;
-+
-+        /* XXX Should check the return value.  */
-+        get_diskinfo (i + 0x80, &geom);
-+        /* FIXME: If HEADS or SECTORS is greater than 255, then this will
-+           break the geometry information. That is a drawback of BSD
-+           but not of GRUB.  */
-+        bi.bi_bios_geom[i] = (((geom.cylinders - 1) << 16)
-+                              + (((geom.heads - 1) & 0xff) << 8)
-+                              + (geom.sectors & 0xff));
-+      }
-+
-+      bi.bi_size = sizeof (struct bootinfo);
-+      bi.bi_memsizes_valid = 1;
-+      bi.bi_bios_dev = saved_drive;
-+      bi.bi_basemem = mbi.mem_lower;
-+      bi.bi_extmem = extended_memory;
-+
-+      if (mbi.flags & MB_INFO_AOUT_SYMS)
-+      {
-+        bi.bi_symtab = mbi.syms.a.addr;
-+        bi.bi_esymtab = mbi.syms.a.addr + 4
-+          + mbi.syms.a.tabsize + mbi.syms.a.strsize;
-+      }
-+#if 0
-+      else if (mbi.flags & MB_INFO_ELF_SHDR)
-+      {
-+        /* FIXME: Should check if a symbol table exists and, if exists,
-+           pass the table to BI.  */
-+      }
-+#endif
-+      else
-+      {
-+        bi.bi_symtab = 0;
-+        bi.bi_esymtab = 0;
-+      }
-+
-+      /* call entry point */
-+      (*entry_addr) (clval, bootdev, 0, 0, 0, ((int) (&bi)));
-+    }
-+  else
-+    {
-+      /*
-+       *  We now pass the various bootstrap parameters to the loaded
-+       *  image via the argument list.
-+       *
-+       *  This is the official list:
-+       *
-+       *  arg0 = 8 (magic)
-+       *  arg1 = boot flags
-+       *  arg2 = boot device
-+       *  arg3 = start of symbol table (0 if not loaded)
-+       *  arg4 = end of symbol table (0 if not loaded)
-+       *  arg5 = transfer address from image
-+       *  arg6 = transfer address for next image pointer
-+       *  arg7 = conventional memory size (640)
-+       *  arg8 = extended memory size (8196)
-+       *
-+       *  ...in actuality, we just pass the parameters used by the kernel.
-+       */
-+
-+      /* call entry point */
-+      unsigned long end_mark;
-+
-+      if (mbi.flags & MB_INFO_AOUT_SYMS)
-+      end_mark = (mbi.syms.a.addr + 4
-+                  + mbi.syms.a.tabsize + mbi.syms.a.strsize);
-+      else
-+      /* FIXME: it should be mbi.syms.e.size.  */
-+      end_mark = 0;
-+      
-+      (*entry_addr) (clval, bootdev, 0, end_mark,
-+                   extended_memory, mbi.mem_lower);
-+    }
-+}
-diff -Nur grub-0.97/stage2/builtins.c grub-0.97-patched/stage2/builtins.c
---- grub-0.97/stage2/builtins.c        2005-02-15 22:58:23.000000000 +0100
-+++ grub-0.97-patched/stage2/builtins.c        2012-11-11 17:07:12.729729661 +0100
-@@ -131,63 +131,98 @@
- }
\f
-+/* 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
-+\f
-+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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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 */
-+
-+\f
-+/* 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"
-+};
-+
\f
- /* 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 @@
\f
- /* 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 @@
- };
\f
--#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 */
\f
- #ifdef SUPPORT_SERIAL
-@@ -4795,6 +4996,9 @@
- /* The table of builtin commands. Sorted in dictionary order.  */
- struct builtin *builtin_table[] =
- {
-+#ifdef SUPPORT_GRAPHICS
-+  &builtin_background,
-+#endif
-   &builtin_blocklist,
-   &builtin_boot,
- #ifdef SUPPORT_NETBOOT
-@@ -4802,6 +5006,7 @@
- #endif /* SUPPORT_NETBOOT */
-   &builtin_cat,
-   &builtin_chainloader,
-+  &builtin_clear,
-   &builtin_cmp,
-   &builtin_color,
-   &builtin_configfile,
-@@ -4821,6 +5026,9 @@
-   &builtin_embed,
-   &builtin_fallback,
-   &builtin_find,
-+#ifdef SUPPORT_GRAPHICS
-+  &builtin_foreground,
-+#endif
-   &builtin_fstest,
-   &builtin_geometry,
-   &builtin_halt,
-@@ -4864,9 +5072,12 @@
- #endif /* SUPPORT_SERIAL */
-   &builtin_setkey,
-   &builtin_setup,
--#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
-+#ifdef SUPPORT_GRAPHICS
-+  &builtin_splashimage,
-+#endif /* SUPPORT_GRAPHICS */
-+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
-   &builtin_terminal,
--#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
-+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
- #ifdef SUPPORT_SERIAL
-   &builtin_terminfo,
- #endif /* SUPPORT_SERIAL */
-diff -Nur grub-0.97/stage2/builtins.c.orig grub-0.97-patched/stage2/builtins.c.orig
---- grub-0.97/stage2/builtins.c.orig   1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/stage2/builtins.c.orig   2005-02-15 22:58:23.000000000 +0100
-@@ -0,0 +1,4884 @@
-+/* builtins.c - the GRUB builtin commands */
-+/*
-+ *  GRUB  --  GRand Unified Bootloader
-+ *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+/* Include stdio.h before shared.h, because we can't define
-+   WITHOUT_LIBC_STUBS here.  */
-+#ifdef GRUB_UTIL
-+# include <stdio.h>
-+#endif
-+
-+#include <shared.h>
-+#include <filesys.h>
-+#include <term.h>
-+
-+#ifdef SUPPORT_NETBOOT
-+# define GRUB 1
-+# include <etherboot.h>
-+#endif
-+
-+#ifdef SUPPORT_SERIAL
-+# include <serial.h>
-+# include <terminfo.h>
-+#endif
-+
-+#ifdef GRUB_UTIL
-+# include <device.h>
-+#else /* ! GRUB_UTIL */
-+# include <apic.h>
-+# include <smp-imps.h>
-+#endif /* ! GRUB_UTIL */
-+
-+#ifdef USE_MD5_PASSWORDS
-+# include <md5.h>
-+#endif
-+
-+/* The type of kernel loaded.  */
-+kernel_t kernel_type;
-+/* The boot device.  */
-+static int bootdev;
-+/* True when the debug mode is turned on, and false
-+   when it is turned off.  */
-+int debug = 0;
-+/* The default entry.  */
-+int default_entry = 0;
-+/* The fallback entry.  */
-+int fallback_entryno;
-+int fallback_entries[MAX_FALLBACK_ENTRIES];
-+/* The number of current entry.  */
-+int current_entryno;
-+/* The address for Multiboot command-line buffer.  */
-+static char *mb_cmdline;
-+/* The password.  */
-+char *password;
-+/* The password type.  */
-+password_t password_type;
-+/* The flag for indicating that the user is authoritative.  */
-+int auth = 0;
-+/* The timeout.  */
-+int grub_timeout = -1;
-+/* Whether to show the menu or not.  */
-+int show_menu = 1;
-+/* The BIOS drive map.  */
-+static unsigned short bios_drive_map[DRIVE_MAP_SIZE + 1];
-+
-+/* Prototypes for allowing straightfoward calling of builtins functions
-+   inside other functions.  */
-+static int configfile_func (char *arg, int flags);
-+
-+/* Initialize the data for builtins.  */
-+void
-+init_builtins (void)
-+{
-+  kernel_type = KERNEL_TYPE_NONE;
-+  /* BSD and chainloading evil hacks!  */
-+  bootdev = set_bootdev (0);
-+  mb_cmdline = (char *) MB_CMDLINE_BUF;
-+}
-+
-+/* Initialize the data for the configuration file.  */
-+void
-+init_config (void)
-+{
-+  default_entry = 0;
-+  password = 0;
-+  fallback_entryno = -1;
-+  fallback_entries[0] = -1;
-+  grub_timeout = -1;
-+}
-+
-+/* Check a password for correctness.  Returns 0 if password was
-+   correct, and a value != 0 for error, similarly to strcmp. */
-+int
-+check_password (char *entered, char* expected, password_t type)
-+{
-+  switch (type)
-+    {
-+    case PASSWORD_PLAIN:
-+      return strcmp (entered, expected);
-+
-+#ifdef USE_MD5_PASSWORDS
-+    case PASSWORD_MD5:
-+      return check_md5_password (entered, expected);
-+#endif
-+    default: 
-+      /* unsupported password type: be secure */
-+      return 1;
-+    }
-+}
-+
-+/* Print which sector is read when loading a file.  */
-+static void
-+disk_read_print_func (int sector, int offset, int length)
-+{
-+  grub_printf ("[%d,%d,%d]", sector, offset, length);
-+}
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+#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 */
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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
-+};
-+
-+\f
-+#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 */
-+
-+\f
-+#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 */
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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 */
-+
-+\f
-+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."
-+};
-+
-+\f
-+/* 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
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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 (&sector, &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."
-+};
-+
-+\f
-+/* 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'."
-+};
-+
-+\f
-+/* 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'."
-+};
-+
-+\f
-+/* 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
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+#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 */
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+  
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+#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 */
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+#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 */
-+
-+\f
-+#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 */
-+
-+\f
-+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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+#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 */
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+#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 */
-+
-+\f
-+#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 */
-+        
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+#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 */
-+
-+\f
-+/* 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
-+};
-+
-+\f
-+/* 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
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+  
-+\f
-+/* The table of builtin commands. Sorted in dictionary order.  */
-+struct builtin *builtin_table[] =
-+{
-+  &builtin_blocklist,
-+  &builtin_boot,
-+#ifdef SUPPORT_NETBOOT
-+  &builtin_bootp,
-+#endif /* SUPPORT_NETBOOT */
-+  &builtin_cat,
-+  &builtin_chainloader,
-+  &builtin_cmp,
-+  &builtin_color,
-+  &builtin_configfile,
-+  &builtin_debug,
-+  &builtin_default,
-+#ifdef GRUB_UTIL
-+  &builtin_device,
-+#endif /* GRUB_UTIL */
-+#ifdef SUPPORT_NETBOOT
-+  &builtin_dhcp,
-+#endif /* SUPPORT_NETBOOT */
-+  &builtin_displayapm,
-+  &builtin_displaymem,
-+#ifdef GRUB_UTIL
-+  &builtin_dump,
-+#endif /* GRUB_UTIL */
-+  &builtin_embed,
-+  &builtin_fallback,
-+  &builtin_find,
-+  &builtin_fstest,
-+  &builtin_geometry,
-+  &builtin_halt,
-+  &builtin_help,
-+  &builtin_hiddenmenu,
-+  &builtin_hide,
-+#ifdef SUPPORT_NETBOOT
-+  &builtin_ifconfig,
-+#endif /* SUPPORT_NETBOOT */
-+  &builtin_impsprobe,
-+  &builtin_initrd,
-+  &builtin_install,
-+  &builtin_ioprobe,
-+  &builtin_kernel,
-+  &builtin_lock,
-+  &builtin_makeactive,
-+  &builtin_map,
-+#ifdef USE_MD5_PASSWORDS
-+  &builtin_md5crypt,
-+#endif /* USE_MD5_PASSWORDS */
-+  &builtin_module,
-+  &builtin_modulenounzip,
-+  &builtin_pager,
-+  &builtin_partnew,
-+  &builtin_parttype,
-+  &builtin_password,
-+  &builtin_pause,
-+#ifdef GRUB_UTIL
-+  &builtin_quit,
-+#endif /* GRUB_UTIL */
-+#ifdef SUPPORT_NETBOOT
-+  &builtin_rarp,
-+#endif /* SUPPORT_NETBOOT */
-+  &builtin_read,
-+  &builtin_reboot,
-+  &builtin_root,
-+  &builtin_rootnoverify,
-+  &builtin_savedefault,
-+#ifdef SUPPORT_SERIAL
-+  &builtin_serial,
-+#endif /* SUPPORT_SERIAL */
-+  &builtin_setkey,
-+  &builtin_setup,
-+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
-+  &builtin_terminal,
-+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
-+#ifdef SUPPORT_SERIAL
-+  &builtin_terminfo,
-+#endif /* SUPPORT_SERIAL */
-+  &builtin_testload,
-+  &builtin_testvbe,
-+#ifdef SUPPORT_NETBOOT
-+  &builtin_tftpserver,
-+#endif /* SUPPORT_NETBOOT */
-+  &builtin_timeout,
-+  &builtin_title,
-+  &builtin_unhide,
-+  &builtin_uppermem,
-+  &builtin_vbeprobe,
-+  0
-+};
-diff -Nur grub-0.97/stage2/char_io.c grub-0.97-patched/stage2/char_io.c
---- grub-0.97/stage2/char_io.c 2005-02-01 21:51:23.000000000 +0100
-+++ grub-0.97-patched/stage2/char_io.c 2012-11-11 17:06:52.556085241 +0100
-@@ -35,6 +35,7 @@
-     {
-       "console",
-       0,
-+      24,
-       console_putchar,
-       console_checkkey,
-       console_getkey,
-@@ -43,13 +44,16 @@
-       console_cls,
-       console_setcolorstate,
-       console_setcolor,
--      console_setcursor
-+      console_setcursor,
-+      0, 
-+      0
-     },
- #ifdef SUPPORT_SERIAL
-     {
-       "serial",
-       /* A serial device must be initialized.  */
-       TERM_NEED_INIT,
-+      24,
-       serial_putchar,
-       serial_checkkey,
-       serial_getkey,
-@@ -58,6 +62,8 @@
-       serial_cls,
-       serial_setcolorstate,
-       0,
-+      0,
-+      0, 
-       0
-     },
- #endif /* SUPPORT_SERIAL */
-@@ -65,6 +71,7 @@
-     {
-       "hercules",
-       0,
-+      24,
-       hercules_putchar,
-       console_checkkey,
-       console_getkey,
-@@ -73,9 +80,28 @@
-       hercules_cls,
-       hercules_setcolorstate,
-       hercules_setcolor,
--      hercules_setcursor
-+      hercules_setcursor,
-+      0,
-+      0
-     },      
- #endif /* SUPPORT_HERCULES */
-+#ifdef SUPPORT_GRAPHICS
-+    { "graphics",
-+      TERM_NEED_INIT, /* flags */
-+      30, /* number of lines */
-+      graphics_putchar, /* putchar */
-+      console_checkkey, /* checkkey */
-+      console_getkey, /* getkey */
-+      graphics_getxy, /* getxy */
-+      graphics_gotoxy, /* gotoxy */
-+      graphics_cls, /* cls */
-+      graphics_setcolorstate, /* setcolorstate */
-+      graphics_setcolor, /* setcolor */
-+      graphics_setcursor, /* nocursor */
-+      graphics_init, /* initialize */
-+      graphics_end /* shutdown */
-+    },
-+#endif /* SUPPORT_GRAPHICS */
-     /* This must be the last entry.  */
-     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-   };
-@@ -1046,13 +1072,15 @@
-                the following grub_printf call will print newlines.  */
-             count_lines = -1;
-+            grub_printf("\n");
-             if (current_term->setcolorstate)
-               current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
-             
--            grub_printf ("\n[Hit return to continue]");
-+            grub_printf ("[Hit return to continue]");
-             if (current_term->setcolorstate)
-               current_term->setcolorstate (COLOR_STATE_NORMAL);
-+              
-             
-             do
-               {
-@@ -1090,7 +1118,7 @@
- cls (void)
- {
-   /* If the terminal is dumb, there is no way to clean the terminal.  */
--  if (current_term->flags & TERM_DUMB)
-+  if (current_term->flags & TERM_DUMB) 
-     grub_putchar ('\n');
-   else
-     current_term->cls ();
-@@ -1174,37 +1202,62 @@
- }
- #endif /* ! STAGE1_5 */
-+#ifdef GRUB_UTIL
-+# ifdef __PIC__
-+#  if defined(HAVE_START_SYMBOL) && defined(HAVE_END_SYMBOL)
-+      extern char start[];
-+      extern char end[];
-+#  elif defined(HAVE_USCORE_START_SYMBOL) && defined (HAVE_USCORE_END_SYMBOL)
-+      extern char _start[];
-+      extern char _end[];
-+#  endif
-+# endif
-+#endif
- int
--memcheck (int addr, int len)
-+memcheck (unsigned long addr, unsigned long len)
- {
- #ifdef GRUB_UTIL
--  auto int start_addr (void);
--  auto int end_addr (void);
-+# ifdef __PIC__
-+#  if defined(HAVE_START_SYMBOL) && defined(HAVE_END_SYMBOL)
-+  if (start <= addr && end > addr + len)
-+    return ! errnum;
-+#  elif defined(HAVE_USCORE_START_SYMBOL) && defined (HAVE_USCORE_END_SYMBOL)
-+  if (_start <= addr && _end > addr + len)
-+    return ! errnum;
-+#  endif
-+# else /* __PIC__ */
-+  auto unsigned long start_addr (void);
-+  auto unsigned long end_addr (void);
-   
--  auto int start_addr (void)
-+  auto unsigned long start_addr (void)
-     {
--      int ret;
--# if defined(HAVE_START_SYMBOL)
-+      unsigned long ret;
-+#  if defined(HAVE_START_SYMBOL)
-       asm volatile ("movl     $start, %0" : "=a" (ret));
--# elif defined(HAVE_USCORE_START_SYMBOL)
-+#  elif defined(HAVE_USCORE_START_SYMBOL)
-       asm volatile ("movl     $_start, %0" : "=a" (ret));
--# endif
-+#  else
-+      erk! /* function would return undefined data in this case - barf */
-+#  endif
-       return ret;
-     }
--  auto int end_addr (void)
-+  auto unsigned long end_addr (void)
-     {
--      int ret;
--# if defined(HAVE_END_SYMBOL)
-+      unsigned long ret;
-+#  if defined(HAVE_END_SYMBOL)
-       asm volatile ("movl     $end, %0" : "=a" (ret));
--# elif defined(HAVE_USCORE_END_SYMBOL)
-+#  elif defined(HAVE_USCORE_END_SYMBOL)
-       asm volatile ("movl     $_end, %0" : "=a" (ret));
--# endif
-+#  else
-+      erk! /* function would return undefined data in this case - barf */
-+#  endif
-       return ret;
-     }
-   if (start_addr () <= addr && end_addr () > addr + len)
-     return ! errnum;
-+# endif /* __PIC__ */
- #endif /* GRUB_UTIL */
-   if ((addr < RAW_ADDR (0x1000))
-@@ -1217,10 +1270,20 @@
-   return ! errnum;
- }
-+void
-+grub_memcpy(void *dest, const void *src, int len)
-+{
-+  int i;
-+  register char *d = (char*)dest, *s = (char*)src;
-+
-+  for (i = 0; i < len; i++)
-+    d[i] = s[i];
-+}
-+
- void *
- grub_memmove (void *to, const void *from, int len)
- {
--   if (memcheck ((int) to, len))
-+   if (memcheck ((unsigned long) to, len))
-      {
-        /* This assembly code is stolen from
-         linux-2.2.2/include/asm-i386/string.h. This is not very fast
-@@ -1258,7 +1321,7 @@
- {
-   char *p = start;
--  if (memcheck ((int) start, len))
-+  if (memcheck ((unsigned long) start, len))
-     {
-       while (len -- > 0)
-       *p ++ = c;
-diff -Nur grub-0.97/stage2/char_io.c.orig grub-0.97-patched/stage2/char_io.c.orig
---- grub-0.97/stage2/char_io.c.orig    1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/stage2/char_io.c.orig    2005-02-01 21:51:23.000000000 +0100
-@@ -0,0 +1,1283 @@
-+/* char_io.c - basic console input and output */
-+/*
-+ *  GRUB  --  GRand Unified Bootloader
-+ *  Copyright (C) 1999,2000,2001,2002,2004  Free Software Foundation, Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include <shared.h>
-+#include <term.h>
-+
-+#ifdef SUPPORT_HERCULES
-+# include <hercules.h>
-+#endif
-+
-+#ifdef SUPPORT_SERIAL
-+# include <serial.h>
-+#endif
-+
-+#ifndef STAGE1_5
-+struct term_entry term_table[] =
-+  {
-+    {
-+      "console",
-+      0,
-+      console_putchar,
-+      console_checkkey,
-+      console_getkey,
-+      console_getxy,
-+      console_gotoxy,
-+      console_cls,
-+      console_setcolorstate,
-+      console_setcolor,
-+      console_setcursor
-+    },
-+#ifdef SUPPORT_SERIAL
-+    {
-+      "serial",
-+      /* A serial device must be initialized.  */
-+      TERM_NEED_INIT,
-+      serial_putchar,
-+      serial_checkkey,
-+      serial_getkey,
-+      serial_getxy,
-+      serial_gotoxy,
-+      serial_cls,
-+      serial_setcolorstate,
-+      0,
-+      0
-+    },
-+#endif /* SUPPORT_SERIAL */
-+#ifdef SUPPORT_HERCULES
-+    {
-+      "hercules",
-+      0,
-+      hercules_putchar,
-+      console_checkkey,
-+      console_getkey,
-+      hercules_getxy,
-+      hercules_gotoxy,
-+      hercules_cls,
-+      hercules_setcolorstate,
-+      hercules_setcolor,
-+      hercules_setcursor
-+    },      
-+#endif /* SUPPORT_HERCULES */
-+    /* This must be the last entry.  */
-+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-+  };
-+
-+/* This must be console.  */
-+struct term_entry *current_term = term_table;
-+
-+int max_lines = 24;
-+int count_lines = -1;
-+int use_pager = 1;
-+#endif
-+
-+void
-+print_error (void)
-+{
-+  if (errnum > ERR_NONE && errnum < MAX_ERR_NUM)
-+#ifndef STAGE1_5
-+    /* printf("\7\n %s\n", err_list[errnum]); */
-+    printf ("\nError %u: %s\n", errnum, err_list[errnum]);
-+#else /* STAGE1_5 */
-+    printf ("Error %u\n", errnum);
-+#endif /* STAGE1_5 */
-+}
-+
-+char *
-+convert_to_ascii (char *buf, int c,...)
-+{
-+  unsigned long num = *((&c) + 1), mult = 10;
-+  char *ptr = buf;
-+
-+#ifndef STAGE1_5
-+  if (c == 'x' || c == 'X')
-+    mult = 16;
-+
-+  if ((num & 0x80000000uL) && c == 'd')
-+    {
-+      num = (~num) + 1;
-+      *(ptr++) = '-';
-+      buf++;
-+    }
-+#endif
-+
-+  do
-+    {
-+      int dig = num % mult;
-+      *(ptr++) = ((dig > 9) ? dig + 'a' - 10 : '0' + dig);
-+    }
-+  while (num /= mult);
-+
-+  /* reorder to correct direction!! */
-+  {
-+    char *ptr1 = ptr - 1;
-+    char *ptr2 = buf;
-+    while (ptr1 > ptr2)
-+      {
-+      int tmp = *ptr1;
-+      *ptr1 = *ptr2;
-+      *ptr2 = tmp;
-+      ptr1--;
-+      ptr2++;
-+      }
-+  }
-+
-+  return ptr;
-+}
-+
-+void
-+grub_putstr (const char *str)
-+{
-+  while (*str)
-+    grub_putchar (*str++);
-+}
-+
-+void
-+grub_printf (const char *format,...)
-+{
-+  int *dataptr = (int *) &format;
-+  char c, str[16];
-+  
-+  dataptr++;
-+
-+  while ((c = *(format++)) != 0)
-+    {
-+      if (c != '%')
-+      grub_putchar (c);
-+      else
-+      switch (c = *(format++))
-+        {
-+#ifndef STAGE1_5
-+        case 'd':
-+        case 'x':
-+        case 'X':
-+#endif
-+        case 'u':
-+          *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
-+          grub_putstr (str);
-+          break;
-+
-+#ifndef STAGE1_5
-+        case 'c':
-+          grub_putchar ((*(dataptr++)) & 0xff);
-+          break;
-+
-+        case 's':
-+          grub_putstr ((char *) *(dataptr++));
-+          break;
-+#endif
-+        }
-+    }
-+}
-+
-+#ifndef STAGE1_5
-+int
-+grub_sprintf (char *buffer, const char *format, ...)
-+{
-+  /* XXX hohmuth
-+     ugly hack -- should unify with printf() */
-+  int *dataptr = (int *) &format;
-+  char c, *ptr, str[16];
-+  char *bp = buffer;
-+
-+  dataptr++;
-+
-+  while ((c = *format++) != 0)
-+    {
-+      if (c != '%')
-+      *bp++ = c; /* putchar(c); */
-+      else
-+      switch (c = *(format++))
-+        {
-+        case 'd': case 'u': case 'x':
-+          *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
-+
-+          ptr = str;
-+
-+          while (*ptr)
-+            *bp++ = *(ptr++); /* putchar(*(ptr++)); */
-+          break;
-+
-+        case 'c': *bp++ = (*(dataptr++))&0xff;
-+          /* putchar((*(dataptr++))&0xff); */
-+          break;
-+
-+        case 's':
-+          ptr = (char *) (*(dataptr++));
-+
-+          while ((c = *ptr++) != 0)
-+            *bp++ = c; /* putchar(c); */
-+          break;
-+        }
-+    }
-+
-+  *bp = 0;
-+  return bp - buffer;
-+}
-+
-+
-+void
-+init_page (void)
-+{
-+  cls ();
-+
-+  grub_printf ("\n    GNU GRUB  version %s  (%dK lower / %dK upper memory)\n\n",
-+        version_string, mbi.mem_lower, mbi.mem_upper);
-+}
-+
-+/* The number of the history entries.  */
-+static int num_history = 0;
-+
-+/* Get the NOth history. If NO is less than zero or greater than or
-+   equal to NUM_HISTORY, return NULL. Otherwise return a valid string.  */
-+static char *
-+get_history (int no)
-+{
-+  if (no < 0 || no >= num_history)
-+    return 0;
-+
-+  return (char *) HISTORY_BUF + MAX_CMDLINE * no;
-+}
-+
-+/* Add CMDLINE to the history buffer.  */
-+static void
-+add_history (const char *cmdline, int no)
-+{
-+  grub_memmove ((char *) HISTORY_BUF + MAX_CMDLINE * (no + 1),
-+              (char *) HISTORY_BUF + MAX_CMDLINE * no,
-+              MAX_CMDLINE * (num_history - no));
-+  grub_strcpy ((char *) HISTORY_BUF + MAX_CMDLINE * no, cmdline);
-+  if (num_history < HISTORY_SIZE)
-+    num_history++;
-+}
-+
-+static int
-+real_get_cmdline (char *prompt, char *cmdline, int maxlen,
-+                int echo_char, int readline)
-+{
-+  /* This is a rather complicated function. So explain the concept.
-+     
-+     A command-line consists of ``section''s. A section is a part of the
-+     line which may be displayed on the screen, but a section is never
-+     displayed with another section simultaneously.
-+
-+     Each section is basically 77 or less characters, but the exception
-+     is the first section, which is 78 or less characters, because the
-+     starting point is special. See below.
-+
-+     The first section contains a prompt and a command-line (or the
-+     first part of a command-line when it is too long to be fit in the
-+     screen). So, in the first section, the number of command-line
-+     characters displayed is 78 minus the length of the prompt (or
-+     less). If the command-line has more characters, `>' is put at the
-+     position 78 (zero-origin), to inform the user of the hidden
-+     characters.
-+
-+     Other sections always have `<' at the first position, since there
-+     is absolutely a section before each section. If there is a section
-+     after another section, this section consists of 77 characters and
-+     `>' at the last position. The last section has 77 or less
-+     characters and doesn't have `>'.
-+
-+     Each section other than the last shares some characters with the
-+     previous section. This region is called ``margin''. If the cursor
-+     is put at the magin which is shared by the first section and the
-+     second, the first section is displayed. Otherwise, a displayed
-+     section is switched to another section, only if the cursor is put
-+     outside that section.  */
-+
-+  /* XXX: These should be defined in shared.h, but I leave these here,
-+     until this code is freezed.  */
-+#define CMDLINE_WIDTH 78
-+#define CMDLINE_MARGIN        10
-+  
-+  int xpos, lpos, c, section;
-+  /* The length of PROMPT.  */
-+  int plen;
-+  /* The length of the command-line.  */
-+  int llen;
-+  /* The index for the history.  */
-+  int history = -1;
-+  /* The working buffer for the command-line.  */
-+  char *buf = (char *) CMDLINE_BUF;
-+  /* The kill buffer.  */
-+  char *kill_buf = (char *) KILL_BUF;
-+  
-+  /* Nested function definitions for code simplicity.  */
-+
-+  /* The forward declarations of nested functions are prefixed
-+     with `auto'.  */
-+  auto void cl_refresh (int full, int len);
-+  auto void cl_backward (int count);
-+  auto void cl_forward (int count);
-+  auto void cl_insert (const char *str);
-+  auto void cl_delete (int count);
-+  auto void cl_init (void);
-+  
-+  /* Move the cursor backward.  */
-+  void cl_backward (int count)
-+    {
-+      lpos -= count;
-+      
-+      /* If the cursor is in the first section, display the first section
-+       instead of the second.  */
-+      if (section == 1 && plen + lpos < CMDLINE_WIDTH)
-+      cl_refresh (1, 0);
-+      else if (xpos - count < 1)
-+      cl_refresh (1, 0);
-+      else
-+      {
-+        xpos -= count;
-+
-+        if (current_term->flags & TERM_DUMB)
-+          {
-+            int i;
-+            
-+            for (i = 0; i < count; i++)
-+              grub_putchar ('\b');
-+          }
-+        else
-+          gotoxy (xpos, getxy () & 0xFF);
-+      }
-+    }
-+
-+  /* Move the cursor forward.  */
-+  void cl_forward (int count)
-+    {
-+      lpos += count;
-+
-+      /* If the cursor goes outside, scroll the screen to the right.  */
-+      if (xpos + count >= CMDLINE_WIDTH)
-+      cl_refresh (1, 0);
-+      else
-+      {
-+        xpos += count;
-+
-+        if (current_term->flags & TERM_DUMB)
-+          {
-+            int i;
-+            
-+            for (i = lpos - count; i < lpos; i++)
-+              {
-+                if (! echo_char)
-+                  grub_putchar (buf[i]);
-+                else
-+                  grub_putchar (echo_char);
-+              }
-+          }
-+        else
-+          gotoxy (xpos, getxy () & 0xFF);
-+      }
-+    }
-+
-+  /* Refresh the screen. If FULL is true, redraw the full line, otherwise,
-+     only LEN characters from LPOS.  */
-+  void cl_refresh (int full, int len)
-+    {
-+      int i;
-+      int start;
-+      int pos = xpos;
-+      
-+      if (full)
-+      {
-+        /* Recompute the section number.  */
-+        if (lpos + plen < CMDLINE_WIDTH)
-+          section = 0;
-+        else
-+          section = ((lpos + plen - CMDLINE_WIDTH)
-+                     / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1);
-+
-+        /* From the start to the end.  */
-+        len = CMDLINE_WIDTH;
-+        pos = 0;
-+        grub_putchar ('\r');
-+
-+        /* If SECTION is the first section, print the prompt, otherwise,
-+           print `<'.  */
-+        if (section == 0)
-+          {
-+            grub_printf ("%s", prompt);
-+            len -= plen;
-+            pos += plen;
-+          }
-+        else
-+          {
-+            grub_putchar ('<');
-+            len--;
-+            pos++;
-+          }
-+      }
-+
-+      /* Compute the index to start writing BUF and the resulting position
-+       on the screen.  */
-+      if (section == 0)
-+      {
-+        int offset = 0;
-+        
-+        if (! full)
-+          offset = xpos - plen;
-+        
-+        start = 0;
-+        xpos = lpos + plen;
-+        start += offset;
-+      }
-+      else
-+      {
-+        int offset = 0;
-+        
-+        if (! full)
-+          offset = xpos - 1;
-+        
-+        start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN)
-+                 + CMDLINE_WIDTH - plen - CMDLINE_MARGIN);
-+        xpos = lpos + 1 - start;
-+        start += offset;
-+      }
-+
-+      /* Print BUF. If ECHO_CHAR is not zero, put it instead.  */
-+      for (i = start; i < start + len && i < llen; i++)
-+      {
-+        if (! echo_char)
-+          grub_putchar (buf[i]);
-+        else
-+          grub_putchar (echo_char);
-+
-+        pos++;
-+      }
-+      
-+      /* Fill up the rest of the line with spaces.  */
-+      for (; i < start + len; i++)
-+      {
-+        grub_putchar (' ');
-+        pos++;
-+      }
-+      
-+      /* If the cursor is at the last position, put `>' or a space,
-+       depending on if there are more characters in BUF.  */
-+      if (pos == CMDLINE_WIDTH)
-+      {
-+        if (start + len < llen)
-+          grub_putchar ('>');
-+        else
-+          grub_putchar (' ');
-+        
-+        pos++;
-+      }
-+      
-+      /* Back to XPOS.  */
-+      if (current_term->flags & TERM_DUMB)
-+      {
-+        for (i = 0; i < pos - xpos; i++)
-+          grub_putchar ('\b');
-+      }
-+      else
-+      gotoxy (xpos, getxy () & 0xFF);
-+    }
-+
-+  /* Initialize the command-line.  */
-+  void cl_init (void)
-+    {
-+      /* Distinguish us from other lines and error messages!  */
-+      grub_putchar ('\n');
-+
-+      /* Print full line and set position here.  */
-+      cl_refresh (1, 0);
-+    }
-+
-+  /* Insert STR to BUF.  */
-+  void cl_insert (const char *str)
-+    {
-+      int l = grub_strlen (str);
-+
-+      if (llen + l < maxlen)
-+      {
-+        if (lpos == llen)
-+          grub_memmove (buf + lpos, str, l + 1);
-+        else
-+          {
-+            grub_memmove (buf + lpos + l, buf + lpos, llen - lpos + 1);
-+            grub_memmove (buf + lpos, str, l);
-+          }
-+        
-+        llen += l;
-+        lpos += l;
-+        if (xpos + l >= CMDLINE_WIDTH)
-+          cl_refresh (1, 0);
-+        else if (xpos + l + llen - lpos > CMDLINE_WIDTH)
-+          cl_refresh (0, CMDLINE_WIDTH - xpos);
-+        else
-+          cl_refresh (0, l + llen - lpos);
-+      }
-+    }
-+
-+  /* Delete COUNT characters in BUF.  */
-+  void cl_delete (int count)
-+    {
-+      grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1);
-+      llen -= count;
-+      
-+      if (xpos + llen + count - lpos > CMDLINE_WIDTH)
-+      cl_refresh (0, CMDLINE_WIDTH - xpos);
-+      else
-+      cl_refresh (0, llen + count - lpos);
-+    }
-+
-+  plen = grub_strlen (prompt);
-+  llen = grub_strlen (cmdline);
-+
-+  if (maxlen > MAX_CMDLINE)
-+    {
-+      maxlen = MAX_CMDLINE;
-+      if (llen >= MAX_CMDLINE)
-+      {
-+        llen = MAX_CMDLINE - 1;
-+        cmdline[MAX_CMDLINE] = 0;
-+      }
-+    }
-+  lpos = llen;
-+  grub_strcpy (buf, cmdline);
-+
-+  cl_init ();
-+
-+  while ((c = ASCII_CHAR (getkey ())) != '\n' && c != '\r')
-+    {
-+      /* If READLINE is non-zero, handle readline-like key bindings.  */
-+      if (readline)
-+      {
-+        switch (c)
-+          {
-+          case 9:             /* TAB lists completions */
-+            {
-+              int i;
-+              /* POS points to the first space after a command.  */
-+              int pos = 0;
-+              int ret;
-+              char *completion_buffer = (char *) COMPLETION_BUF;
-+              int equal_pos = -1;
-+              int is_filename;
-+
-+              /* Find the first word.  */
-+              while (buf[pos] == ' ')
-+                pos++;
-+              while (buf[pos] && buf[pos] != '=' && buf[pos] != ' ')
-+                pos++;
-+
-+              is_filename = (lpos > pos);
-+
-+              /* Find the position of the equal character after a
-+                 command, and replace it with a space.  */
-+              for (i = pos; buf[i] && buf[i] != ' '; i++)
-+                if (buf[i] == '=')
-+                  {
-+                    equal_pos = i;
-+                    buf[i] = ' ';
-+                    break;
-+                  }
-+
-+              /* Find the position of the first character in this
-+                 word.  */
-+              for (i = lpos; i > 0 && buf[i - 1] != ' '; i--)
-+                ;
-+
-+              /* Invalidate the cache, because the user may exchange
-+                 removable disks.  */
-+              buf_drive = -1;
-+
-+              /* Copy this word to COMPLETION_BUFFER and do the
-+                 completion.  */
-+              grub_memmove (completion_buffer, buf + i, lpos - i);
-+              completion_buffer[lpos - i] = 0;
-+              ret = print_completions (is_filename, 1);
-+              errnum = ERR_NONE;
-+
-+              if (ret >= 0)
-+                {
-+                  /* Found, so insert COMPLETION_BUFFER.  */
-+                  cl_insert (completion_buffer + lpos - i);
-+
-+                  if (ret > 0)
-+                    {
-+                      /* There are more than one candidates, so print
-+                         the list.  */
-+                      grub_putchar ('\n');
-+                      print_completions (is_filename, 0);
-+                      errnum = ERR_NONE;
-+                    }
-+                }
-+
-+              /* Restore the command-line.  */
-+              if (equal_pos >= 0)
-+                buf[equal_pos] = '=';
-+
-+              if (ret)
-+                cl_init ();
-+            }
-+            break;
-+          case 1:             /* C-a go to beginning of line */
-+            cl_backward (lpos);
-+            break;
-+          case 5:             /* C-e go to end of line */
-+            cl_forward (llen - lpos);
-+            break;
-+          case 6:             /* C-f forward one character */
-+            if (lpos < llen)
-+              cl_forward (1);
-+            break;
-+          case 2:             /* C-b backward one character */
-+            if (lpos > 0)
-+              cl_backward (1);
-+            break;
-+          case 21:            /* C-u kill to beginning of line */
-+            if (lpos == 0)
-+              break;
-+            /* Copy the string being deleted to KILL_BUF.  */
-+            grub_memmove (kill_buf, buf, lpos);
-+            kill_buf[lpos] = 0;
-+            {
-+              /* XXX: Not very clever.  */
-+              
-+              int count = lpos;
-+              
-+              cl_backward (lpos);
-+              cl_delete (count);
-+            }
-+            break;
-+          case 11:            /* C-k kill to end of line */
-+            if (lpos == llen)
-+              break;
-+            /* Copy the string being deleted to KILL_BUF.  */
-+            grub_memmove (kill_buf, buf + lpos, llen - lpos + 1);
-+            cl_delete (llen - lpos);
-+            break;
-+          case 25:            /* C-y yank the kill buffer */
-+            cl_insert (kill_buf);
-+            break;
-+          case 16:            /* C-p fetch the previous command */
-+            {
-+              char *p;
-+
-+              if (history < 0)
-+                /* Save the working buffer.  */
-+                grub_strcpy (cmdline, buf);
-+              else if (grub_strcmp (get_history (history), buf) != 0)
-+                /* If BUF is modified, add it into the history list.  */
-+                add_history (buf, history);
-+
-+              history++;
-+              p = get_history (history);
-+              if (! p)
-+                {
-+                  history--;
-+                  break;
-+                }
-+
-+              grub_strcpy (buf, p);
-+              llen = grub_strlen (buf);
-+              lpos = llen;
-+              cl_refresh (1, 0);
-+            }
-+            break;
-+          case 14:            /* C-n fetch the next command */
-+            {
-+              char *p;
-+
-+              if (history < 0)
-+                {
-+                  break;
-+                }
-+              else if (grub_strcmp (get_history (history), buf) != 0)
-+                /* If BUF is modified, add it into the history list.  */
-+                add_history (buf, history);
-+
-+              history--;
-+              p = get_history (history);
-+              if (! p)
-+                p = cmdline;
-+
-+              grub_strcpy (buf, p);
-+              llen = grub_strlen (buf);
-+              lpos = llen;
-+              cl_refresh (1, 0);
-+            }
-+            break;
-+          }
-+      }
-+
-+      /* ESC, C-d and C-h are always handled. Actually C-d is not
-+       functional if READLINE is zero, as the cursor cannot go
-+       backward, but that's ok.  */
-+      switch (c)
-+      {
-+      case 27:        /* ESC immediately return 1 */
-+        return 1;
-+      case 4:         /* C-d delete character under cursor */
-+        if (lpos == llen)
-+          break;
-+        cl_delete (1);
-+        break;
-+      case 8:         /* C-h backspace */
-+# ifdef GRUB_UTIL
-+      case 127:       /* also backspace */
-+# endif
-+        if (lpos > 0)
-+          {
-+            cl_backward (1);
-+            cl_delete (1);
-+          }
-+        break;
-+      default:                /* insert printable character into line */
-+        if (c >= ' ' && c <= '~')
-+          {
-+            char str[2];
-+
-+            str[0] = c;
-+            str[1] = 0;
-+            cl_insert (str);
-+          }
-+      }
-+    }
-+
-+  grub_putchar ('\n');
-+
-+  /* If ECHO_CHAR is NUL, remove the leading spaces.  */
-+  lpos = 0;
-+  if (! echo_char)
-+    while (buf[lpos] == ' ')
-+      lpos++;
-+
-+  /* Copy the working buffer to CMDLINE.  */
-+  grub_memmove (cmdline, buf + lpos, llen - lpos + 1);
-+
-+  /* If the readline-like feature is turned on and CMDLINE is not
-+     empty, add it into the history list.  */
-+  if (readline && lpos < llen)
-+    add_history (cmdline, 0);
-+
-+  return 0;
-+}
-+
-+/* Don't use this with a MAXLEN greater than 1600 or so!  The problem
-+   is that GET_CMDLINE depends on the everything fitting on the screen
-+   at once.  So, the whole screen is about 2000 characters, minus the
-+   PROMPT, and space for error and status lines, etc.  MAXLEN must be
-+   at least 1, and PROMPT and CMDLINE must be valid strings (not NULL
-+   or zero-length).
-+
-+   If ECHO_CHAR is nonzero, echo it instead of the typed character. */
-+int
-+get_cmdline (char *prompt, char *cmdline, int maxlen,
-+           int echo_char, int readline)
-+{
-+  int old_cursor;
-+  int ret;
-+
-+  old_cursor = setcursor (1);
-+  
-+  /* Because it is hard to deal with different conditions simultaneously,
-+     less functional cases are handled here. Assume that TERM_NO_ECHO
-+     implies TERM_NO_EDIT.  */
-+  if (current_term->flags & (TERM_NO_ECHO | TERM_NO_EDIT))
-+    {
-+      char *p = cmdline;
-+      int c;
-+      
-+      /* Make sure that MAXLEN is not too large.  */
-+      if (maxlen > MAX_CMDLINE)
-+      maxlen = MAX_CMDLINE;
-+
-+      /* Print only the prompt. The contents of CMDLINE is simply discarded,
-+       even if it is not empty.  */
-+      grub_printf ("%s", prompt);
-+
-+      /* Gather characters until a newline is gotten.  */
-+      while ((c = ASCII_CHAR (getkey ())) != '\n' && c != '\r')
-+      {
-+        /* Return immediately if ESC is pressed.  */
-+        if (c == 27)
-+          {
-+            setcursor (old_cursor);
-+            return 1;
-+          }
-+
-+        /* Printable characters are added into CMDLINE.  */
-+        if (c >= ' ' && c <= '~')
-+          {
-+            if (! (current_term->flags & TERM_NO_ECHO))
-+              grub_putchar (c);
-+
-+            /* Preceding space characters must be ignored.  */
-+            if (c != ' ' || p != cmdline)
-+              *p++ = c;
-+          }
-+      }
-+
-+      *p = 0;
-+
-+      if (! (current_term->flags & TERM_NO_ECHO))
-+      grub_putchar ('\n');
-+
-+      setcursor (old_cursor);
-+      return 0;
-+    }
-+
-+  /* Complicated features are left to real_get_cmdline.  */
-+  ret = real_get_cmdline (prompt, cmdline, maxlen, echo_char, readline);
-+  setcursor (old_cursor);
-+  return ret;
-+}
-+
-+int
-+safe_parse_maxint (char **str_ptr, int *myint_ptr)
-+{
-+  char *ptr = *str_ptr;
-+  int myint = 0;
-+  int mult = 10, found = 0;
-+
-+  /*
-+   *  Is this a hex number?
-+   */
-+  if (*ptr == '0' && tolower (*(ptr + 1)) == 'x')
-+    {
-+      ptr += 2;
-+      mult = 16;
-+    }
-+
-+  while (1)
-+    {
-+      /* A bit tricky. This below makes use of the equivalence:
-+       (A >= B && A <= C) <=> ((A - B) <= (C - B))
-+       when C > B and A is unsigned.  */
-+      unsigned int digit;
-+
-+      digit = tolower (*ptr) - '0';
-+      if (digit > 9)
-+      {
-+        digit -= 'a' - '0';
-+        if (mult == 10 || digit > 5)
-+          break;
-+        digit += 10;
-+      }
-+
-+      found = 1;
-+      if (myint > ((MAXINT - digit) / mult))
-+      {
-+        errnum = ERR_NUMBER_OVERFLOW;
-+        return 0;
-+      }
-+      myint = (myint * mult) + digit;
-+      ptr++;
-+    }
-+
-+  if (!found)
-+    {
-+      errnum = ERR_NUMBER_PARSING;
-+      return 0;
-+    }
-+
-+  *str_ptr = ptr;
-+  *myint_ptr = myint;
-+
-+  return 1;
-+}
-+#endif /* STAGE1_5 */
-+
-+#if !defined(STAGE1_5) || defined(FSYS_FAT)
-+int
-+grub_tolower (int c)
-+{
-+  if (c >= 'A' && c <= 'Z')
-+    return (c + ('a' - 'A'));
-+
-+  return c;
-+}
-+#endif /* ! STAGE1_5 || FSYS_FAT */
-+
-+int
-+grub_isspace (int c)
-+{
-+  switch (c)
-+    {
-+    case ' ':
-+    case '\t':
-+    case '\r':
-+    case '\n':
-+      return 1;
-+    default:
-+      break;
-+    }
-+
-+  return 0;
-+}
-+
-+#if !defined(STAGE1_5) || defined(FSYS_ISO9660)
-+int
-+grub_memcmp (const char *s1, const char *s2, int n)
-+{
-+  while (n)
-+    {
-+      if (*s1 < *s2)
-+      return -1;
-+      else if (*s1 > *s2)
-+      return 1;
-+      s1++;
-+      s2++;
-+      n--;
-+    }
-+
-+  return 0;
-+}
-+#endif /* ! STAGE1_5 || FSYS_ISO9660 */
-+
-+#ifndef STAGE1_5
-+int
-+grub_strncat (char *s1, const char *s2, int n)
-+{
-+  int i = -1;
-+
-+  while (++i < n && s1[i] != 0);
-+
-+  while (i < n && (s1[i++] = *(s2++)) != 0);
-+
-+  s1[n - 1] = 0;
-+
-+  if (i >= n)
-+    return 0;
-+
-+  s1[i] = 0;
-+
-+  return 1;
-+}
-+#endif /* ! STAGE1_5 */
-+
-+/* XXX: This below is an evil hack. Certainly, we should change the
-+   strategy to determine what should be defined and what shouldn't be
-+   defined for each image. For example, it would be better to create
-+   a static library supporting minimal standard C functions and link
-+   each image with the library. Complicated things should be left to
-+   computer, definitely. -okuji  */
-+#if !defined(STAGE1_5) || defined(FSYS_VSTAFS)
-+int
-+grub_strcmp (const char *s1, const char *s2)
-+{
-+  while (*s1 || *s2)
-+    {
-+      if (*s1 < *s2)
-+      return -1;
-+      else if (*s1 > *s2)
-+      return 1;
-+      s1 ++;
-+      s2 ++;
-+    }
-+
-+  return 0;
-+}
-+#endif /* ! STAGE1_5 || FSYS_VSTAFS */
-+
-+#ifndef STAGE1_5
-+/* Wait for a keypress and return its code.  */
-+int
-+getkey (void)
-+{
-+  return current_term->getkey ();
-+}
-+
-+/* Check if a key code is available.  */
-+int
-+checkkey (void)
-+{
-+  return current_term->checkkey ();
-+}
-+#endif /* ! STAGE1_5 */
-+
-+/* Display an ASCII character.  */
-+void
-+grub_putchar (int c)
-+{
-+  if (c == '\n')
-+    grub_putchar ('\r');
-+#ifndef STAGE1_5
-+  else if (c == '\t' && current_term->getxy)
-+    {
-+      int n;
-+      
-+      n = 8 - ((current_term->getxy () >> 8) & 3);
-+      while (n--)
-+      grub_putchar (' ');
-+      
-+      return;
-+    }
-+#endif /* ! STAGE1_5 */
-+  
-+#ifdef STAGE1_5
-+  
-+  /* In Stage 1.5, only the normal console is supported.  */
-+  console_putchar (c);
-+  
-+#else /* ! STAGE1_5 */
-+
-+  if (c == '\n')
-+    {
-+      /* Internal `more'-like feature.  */
-+      if (count_lines >= 0)
-+      {
-+        count_lines++;
-+        if (count_lines >= max_lines - 2)
-+          {
-+            int tmp;
-+            
-+            /* It's important to disable the feature temporarily, because
-+               the following grub_printf call will print newlines.  */
-+            count_lines = -1;
-+
-+            if (current_term->setcolorstate)
-+              current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
-+            
-+            grub_printf ("\n[Hit return to continue]");
-+
-+            if (current_term->setcolorstate)
-+              current_term->setcolorstate (COLOR_STATE_NORMAL);
-+            
-+            do
-+              {
-+                tmp = ASCII_CHAR (getkey ());
-+              }
-+            while (tmp != '\n' && tmp != '\r');
-+            grub_printf ("\r                        \r");
-+            
-+            /* Restart to count lines.  */
-+            count_lines = 0;
-+            return;
-+          }
-+      }
-+    }
-+
-+  current_term->putchar (c);
-+  
-+#endif /* ! STAGE1_5 */
-+}
-+
-+#ifndef STAGE1_5
-+void
-+gotoxy (int x, int y)
-+{
-+  current_term->gotoxy (x, y);
-+}
-+
-+int
-+getxy (void)
-+{
-+  return current_term->getxy ();
-+}
-+
-+void
-+cls (void)
-+{
-+  /* If the terminal is dumb, there is no way to clean the terminal.  */
-+  if (current_term->flags & TERM_DUMB)
-+    grub_putchar ('\n');
-+  else
-+    current_term->cls ();
-+}
-+
-+int
-+setcursor (int on)
-+{
-+  if (current_term->setcursor)
-+    return current_term->setcursor (on);
-+
-+  return 1;
-+}
-+#endif /* ! STAGE1_5 */
-+
-+int
-+substring (const char *s1, const char *s2)
-+{
-+  while (*s1 == *s2)
-+    {
-+      /* The strings match exactly. */
-+      if (! *(s1++))
-+      return 0;
-+      s2 ++;
-+    }
-+
-+  /* S1 is a substring of S2. */
-+  if (*s1 == 0)
-+    return -1;
-+
-+  /* S1 isn't a substring. */
-+  return 1;
-+}
-+
-+#ifndef STAGE1_5
-+/* Terminate the string STR with NUL.  */
-+int
-+nul_terminate (char *str)
-+{
-+  int ch;
-+  
-+  while (*str && ! grub_isspace (*str))
-+    str++;
-+
-+  ch = *str;
-+  *str = 0;
-+  return ch;
-+}
-+
-+char *
-+grub_strstr (const char *s1, const char *s2)
-+{
-+  while (*s1)
-+    {
-+      const char *ptr, *tmp;
-+
-+      ptr = s1;
-+      tmp = s2;
-+
-+      while (*tmp && *ptr == *tmp)
-+      ptr++, tmp++;
-+      
-+      if (tmp > s2 && ! *tmp)
-+      return (char *) s1;
-+
-+      s1++;
-+    }
-+
-+  return 0;
-+}
-+
-+int
-+grub_strlen (const char *str)
-+{
-+  int len = 0;
-+
-+  while (*str++)
-+    len++;
-+
-+  return len;
-+}
-+#endif /* ! STAGE1_5 */
-+
-+int
-+memcheck (int addr, int len)
-+{
-+#ifdef GRUB_UTIL
-+  auto int start_addr (void);
-+  auto int end_addr (void);
-+  
-+  auto int start_addr (void)
-+    {
-+      int ret;
-+# if defined(HAVE_START_SYMBOL)
-+      asm volatile ("movl     $start, %0" : "=a" (ret));
-+# elif defined(HAVE_USCORE_START_SYMBOL)
-+      asm volatile ("movl     $_start, %0" : "=a" (ret));
-+# endif
-+      return ret;
-+    }
-+
-+  auto int end_addr (void)
-+    {
-+      int ret;
-+# if defined(HAVE_END_SYMBOL)
-+      asm volatile ("movl     $end, %0" : "=a" (ret));
-+# elif defined(HAVE_USCORE_END_SYMBOL)
-+      asm volatile ("movl     $_end, %0" : "=a" (ret));
-+# endif
-+      return ret;
-+    }
-+
-+  if (start_addr () <= addr && end_addr () > addr + len)
-+    return ! errnum;
-+#endif /* GRUB_UTIL */
-+
-+  if ((addr < RAW_ADDR (0x1000))
-+      || (addr < RAW_ADDR (0x100000)
-+        && RAW_ADDR (mbi.mem_lower * 1024) < (addr + len))
-+      || (addr >= RAW_ADDR (0x100000)
-+        && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len)))
-+    errnum = ERR_WONT_FIT;
-+
-+  return ! errnum;
-+}
-+
-+void *
-+grub_memmove (void *to, const void *from, int len)
-+{
-+   if (memcheck ((int) to, len))
-+     {
-+       /* This assembly code is stolen from
-+        linux-2.2.2/include/asm-i386/string.h. This is not very fast
-+        but compact.  */
-+       int d0, d1, d2;
-+
-+       if (to < from)
-+       {
-+         asm volatile ("cld\n\t"
-+                       "rep\n\t"
-+                       "movsb"
-+                       : "=&c" (d0), "=&S" (d1), "=&D" (d2)
-+                       : "0" (len),"1" (from),"2" (to)
-+                       : "memory");
-+       }
-+       else
-+       {
-+         asm volatile ("std\n\t"
-+                       "rep\n\t"
-+                       "movsb\n\t"
-+                       "cld"
-+                       : "=&c" (d0), "=&S" (d1), "=&D" (d2)
-+                       : "0" (len),
-+                       "1" (len - 1 + (const char *) from),
-+                       "2" (len - 1 + (char *) to)
-+                       : "memory");
-+       }
-+     }
-+
-+   return errnum ? NULL : to;
-+}
-+
-+void *
-+grub_memset (void *start, int c, int len)
-+{
-+  char *p = start;
-+
-+  if (memcheck ((int) start, len))
-+    {
-+      while (len -- > 0)
-+      *p ++ = c;
-+    }
-+
-+  return errnum ? NULL : start;
-+}
-+
-+#ifndef STAGE1_5
-+char *
-+grub_strcpy (char *dest, const char *src)
-+{
-+  grub_memmove (dest, src, grub_strlen (src) + 1);
-+  return dest;
-+}
-+#endif /* ! STAGE1_5 */
-+
-+#ifndef GRUB_UTIL
-+# undef memcpy
-+/* GCC emits references to memcpy() for struct copies etc.  */
-+void *memcpy (void *dest, const void *src, int n)  __attribute__ ((alias ("grub_memmove")));
-+#endif
-diff -Nur grub-0.97/stage2/common.c grub-0.97-patched/stage2/common.c
---- grub-0.97/stage2/common.c  2004-03-27 17:25:44.000000000 +0100
-+++ grub-0.97-patched/stage2/common.c  2012-11-11 17:06:52.558085305 +0100
-@@ -142,7 +142,8 @@
- init_bios_info (void)
- {
- #ifndef STAGE1_5
--  unsigned long cont, memtmp, addr;
-+  unsigned long memtmp, addr;
-+  volatile unsigned long cont;
-   int drive;
- #endif
-diff -Nur grub-0.97/stage2/disk_io.c grub-0.97-patched/stage2/disk_io.c
---- grub-0.97/stage2/disk_io.c 2004-05-23 18:35:24.000000000 +0200
-+++ grub-0.97-patched/stage2/disk_io.c 2012-11-11 17:07:12.740730013 +0100
-@@ -21,6 +21,7 @@
- #include <shared.h>
- #include <filesys.h>
-+#include <gpt.h>
- #ifdef SUPPORT_NETBOOT
- # define GRUB 1
-@@ -137,7 +138,7 @@
- }
- int
--rawread (int drive, int sector, int byte_offset, int byte_len, char *buf)
-+rawread (int drive, unsigned int sector, int byte_offset, int byte_len, char *buf)
- {
-   int slen, sectors_per_vtrack;
-   int sector_size_bits = log2 (buf_geom.sector_size);
-@@ -261,7 +262,7 @@
-        */
-       if (disk_read_func)
-       {
--        int sector_num = sector;
-+        unsigned int sector_num = sector;
-         int length = buf_geom.sector_size - byte_offset;
-         if (length > size)
-           length = size;
-@@ -291,7 +292,7 @@
- int
--devread (int sector, int byte_offset, int byte_len, char *buf)
-+devread (unsigned int sector, int byte_offset, int byte_len, char *buf)
- {
-   /*
-    *  Check partition boundaries
-@@ -330,7 +331,7 @@
- #ifndef STAGE1_5
- int
--rawwrite (int drive, int sector, char *buf)
-+rawwrite (int drive, unsigned int sector, char *buf)
- {
-   if (sector == 0)
-     {
-@@ -363,7 +364,7 @@
- }
- int
--devwrite (int sector, int sector_count, char *buf)
-+devwrite (unsigned int sector, int sector_count, char *buf)
- {
- #if defined(GRUB_UTIL) && defined(__linux__)
-   if (current_partition != 0xFFFFFF
-@@ -502,8 +503,8 @@
- set_partition_hidden_flag (int hidden)
- {
-   unsigned long part = 0xFFFFFF;
--  unsigned long start, len, offset, ext_offset;
--  int entry, type;
-+  unsigned long start, len, offset, ext_offset, gpt_offset;
-+  int entry, type, gpt_count, gpt_size;
-   char mbr[512];
-   
-   /* The drive must be a hard disk.  */
-@@ -524,8 +525,15 @@
-   /* Look for the partition.  */
-   while (next_partition (current_drive, 0xFFFFFF, &part, &type,           
-                        &start, &len, &offset, &entry,
--                       &ext_offset, mbr))
-+                       &ext_offset, &gpt_offset, &gpt_count, &gpt_size, mbr))
-     {                                                                       
-+        /* The partition may not be a GPT partition.  */
-+        if (gpt_offset != 0)
-+          {
-+              errnum = ERR_BAD_ARGUMENT;
-+              return 1;
-+          }
-+
-       if (part == current_partition)
-       {
-         /* Found.  */
-@@ -577,11 +585,14 @@
-               unsigned long *partition, int *type,
-               unsigned long *start, unsigned long *len,
-               unsigned long *offset, int *entry,
--              unsigned long *ext_offset, char *buf)
-+               unsigned long *ext_offset,
-+               unsigned long *gpt_offset, int *gpt_count,
-+               int *gpt_size, char *buf)
- {
-   /* Forward declarations.  */
-   auto int next_bsd_partition (void);
-   auto int next_pc_slice (void);
-+  auto int next_gpt_slice(void);
-   /* Get next BSD partition in current PC slice.  */
-   int next_bsd_partition (void)
-@@ -666,6 +677,40 @@
-         return 0;
-       }
-+      /* If this is a GPT partition table, read it as such.  */
-+      if (*entry == -1 && *offset == 0 && PC_SLICE_TYPE (buf, 0) == PC_SLICE_TYPE_GPT)
-+       {
-+         struct grub_gpt_header *hdr = (struct grub_gpt_header *) buf;
-+
-+         /* Read in the GPT Partition table header.  */
-+         if (! rawread (drive, 1, 0, SECTOR_SIZE, buf))
-+           return 0;
-+
-+         if (hdr->magic == GPT_HEADER_MAGIC && hdr->version == 0x10000)
-+           {
-+             /* Let gpt_offset point to the first entry in the GPT
-+                partition table.  This can also be used by callers of
-+                next_partition to determine if a entry comes from a
-+                GPT partition table or not.  */
-+             *gpt_offset = hdr->partitions;
-+             *gpt_count = hdr->maxpart;
-+             *gpt_size =  hdr->partentry_size;
-+             
-+             return next_gpt_slice();
-+           }
-+         else
-+           {
-+             /* This is not a valid header for a GPT partition table.
-+                Re-read the MBR or the boot sector of the extended
-+                partition.  */
-+             if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf))
-+               return 0;
-+           }
-+       }
-+
-+      /* Not a GPT partition.  */
-+      *gpt_offset = 0;
-+
-       /* Increase the entry number.  */
-       (*entry)++;
-@@ -710,6 +755,43 @@
-       return 1;
-     }
-+  /* Get the next GPT slice.  */
-+  int next_gpt_slice (void)
-+    {
-+      struct grub_gpt_partentry *gptentry = (struct grub_gpt_partentry *) buf;
-+      /* Make GPT partitions show up as PC slices.  */
-+      int pc_slice_no = (*partition & 0xFF0000) >> 16;
-+
-+      /* If this is the first time...  */
-+      if (pc_slice_no == 0xFF)
-+       {
-+         pc_slice_no = -1;
-+         *entry = -1;
-+       }
-+
-+      do {
-+       (*entry)++;
-+
-+       if (*entry >= *gpt_count)
-+         {
-+           errnum = ERR_NO_PART;
-+           return 0;
-+         }
-+       /* Read in the GPT Partition table entry.  */
-+       if (! rawread (drive, (*gpt_offset) + GPT_ENTRY_SECTOR (*gpt_size, *entry), GPT_ENTRY_INDEX (*gpt_size, *entry), *gpt_size, buf))
-+         return 0;
-+      } while (! (gptentry->type1 && gptentry->type2));
-+
-+      pc_slice_no++;
-+      *start = gptentry->start;
-+      *len = gptentry->end - gptentry->start + 1;
-+      *type = PC_SLICE_TYPE_EXT2FS;
-+      *entry = pc_slice_no;
-+      *partition = (*entry << 16) | 0xFFFF;
-+
-+      return 1;
-+    }
-+
-   /* Start the body of this function.  */
-   
- #ifndef STAGE1_5
-@@ -717,6 +799,9 @@
-     return 0;
- #endif
-+  if (*partition != 0xFFFFFF && *gpt_offset != 0)
-+    return next_gpt_slice ();
-+
-   /* If previous partition is a BSD partition or a PC slice which
-      contains BSD partitions...  */
-   if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff))
-@@ -746,6 +831,8 @@
- #ifndef STAGE1_5
- static unsigned long cur_part_offset;
- static unsigned long cur_part_addr;
-+static unsigned long cur_part_start;
-+static int cur_part_entry;
- #endif
- /* Open a partition.  */
-@@ -755,6 +842,9 @@
-   unsigned long dest_partition = current_partition;
-   unsigned long part_offset;
-   unsigned long ext_offset;
-+  unsigned long gpt_offset;
-+  int gpt_count;
-+  int gpt_size;
-   int entry;
-   char buf[SECTOR_SIZE];
-   int bsd_part, pc_slice;
-@@ -766,7 +856,8 @@
-       int ret = next_partition (current_drive, dest_partition,
-                               &current_partition, &current_slice,
-                               &part_start, &part_length,
--                              &part_offset, &entry, &ext_offset, buf);
-+                               &part_offset, &entry, &ext_offset,
-+                               &gpt_offset, &gpt_count, &gpt_size, buf);
-       bsd_part = (current_partition >> 8) & 0xFF;
-       pc_slice = current_partition >> 16;
-       return ret;
-@@ -800,7 +891,12 @@
-   /* If this is the whole disk, return here.  */
-   if (! flags && current_partition == 0xFFFFFF)
--    return 1;
-+    {
-+#ifndef STAGE1_5
-+      cur_part_offset = 0;
-+#endif /* ! STAGE1_5 */
-+      return 1;
-+    }
-   if (flags)
-     dest_partition = 0xFFFFFF;
-@@ -815,6 +911,8 @@
-       
-       cur_part_offset = part_offset;
-       cur_part_addr = BOOT_PART_TABLE + (entry << 4);
-+      cur_part_start = part_start;
-+      cur_part_entry = entry;
- #endif /* ! STAGE1_5 */
-       /* If this is a valid partition...  */
-@@ -1142,6 +1240,7 @@
-         src = (char *) SCRATCHADDR + BOOTSEC_PART_OFFSET;
-         while (dst < (char *) BOOT_PART_TABLE + BOOTSEC_PART_LENGTH)
-           *dst++ = *src++;
-+        PC_SLICE_START (BOOT_PART_TABLE - PC_SLICE_OFFSET, cur_part_entry) = cur_part_start;
-         
-         /* Set the active flag of the booted partition.  */
-         for (i = 0; i < 4; i++)
-diff -Nur grub-0.97/stage2/fsys_ext2fs.c grub-0.97-patched/stage2/fsys_ext2fs.c
---- grub-0.97/stage2/fsys_ext2fs.c     2004-08-08 20:19:18.000000000 +0200
-+++ grub-0.97-patched/stage2/fsys_ext2fs.c     2012-11-11 17:07:12.750730331 +0100
-@@ -41,6 +41,7 @@
- typedef unsigned short __u16;
- typedef __signed__ int __s32;
- typedef unsigned int __u32;
-+typedef unsigned long long __u64;
- /*
-  * Constants relative to the data blocks, from ext2_fs.h
-@@ -61,9 +62,9 @@
-     __u32 s_free_inodes_count;        /* Free inodes count */
-     __u32 s_first_data_block; /* First Data Block */
-     __u32 s_log_block_size;   /* Block size */
--    __s32 s_log_frag_size;    /* Fragment size */
-+    __s32 s_obso_log_frag_size;       /* Obsoleted Fragment size */
-     __u32 s_blocks_per_group; /* # Blocks per group */
--    __u32 s_frags_per_group;  /* # Fragments per group */
-+    __u32 s_obso_frags_per_group;     /* Obsoleted Fragments per group */
-     __u32 s_inodes_per_group; /* # Inodes per group */
-     __u32 s_mtime;            /* Mount time */
-     __u32 s_wtime;            /* Write time */
-@@ -72,17 +73,62 @@
-     __u16 s_magic;            /* Magic signature */
-     __u16 s_state;            /* File system state */
-     __u16 s_errors;           /* Behaviour when detecting errors */
--    __u16 s_pad;
-+    __u16 s_minor_rev_level;  /* minor revision level */
-     __u32 s_lastcheck;                /* time of last check */
-     __u32 s_checkinterval;    /* max. time between checks */
-     __u32 s_creator_os;               /* OS */
-     __u32 s_rev_level;                /* Revision level */
-     __u16 s_def_resuid;               /* Default uid for reserved blocks */
-     __u16 s_def_resgid;               /* Default gid for reserved blocks */
--    __u32 s_reserved[235];    /* Padding to the end of the block */
-+    /*
-+     * These fields are for EXT2_DYNAMIC_REV superblocks only.
-+     *
-+     * Note: the difference between the compatible feature set and
-+     * the incompatible feature set is that if there is a bit set
-+     * in the incompatible feature set that the kernel doesn't
-+     * know about, it should refuse to mount the filesystem.
-+     *
-+     * e2fsck's requirements are more strict; if it doesn't know
-+     * about a feature in either the compatible or incompatible
-+     * feature set, it must abort and not try to meddle with
-+     * things it doesn't understand...
-+     */
-+    __u32 s_first_ino;                /* First non-reserved inode */
-+    __u16 s_inode_size;               /* size of inode structure */
-+    __u16 s_block_group_nr;   /* block group # of this superblock */
-+    __u32 s_feature_compat;   /* compatible feature set */
-+    __u32 s_feature_incompat; /* incompatible feature set */
-+    __u32 s_feature_ro_compat;        /* readonly-compatible feature set */
-+    __u8  s_uuid[16];         /* 128-bit uuid for volume */
-+    char  s_volume_name[16];  /* volume name */
-+    char  s_last_mounted[64]; /* directory where last mounted */
-+    __u32 s_algorithm_usage_bitmap; /* For compression */
-+    /*
-+     * Performance hints.  Directory preallocation should only
-+     * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
-+     */
-+    __u8  s_prealloc_blocks;  /* Nr of blocks to try to preallocate*/
-+    __u8  s_prealloc_dir_blocks;      /* Nr to preallocate for dirs */
-+    __u16 s_reserved_gdt_blocks;/* Per group table for online growth */
-+    /*
-+     * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
-+     */
-+    __u8 s_journal_uuid[16];  /* uuid of journal superblock */
-+    __u32 s_journal_inum;     /* inode number of journal file */
-+    __u32 s_journal_dev;      /* device number of journal file */
-+    __u32 s_last_orphan;      /* start of list of inodes to delete */
-+    __u32 s_hash_seed[4];     /* HTREE hash seed */
-+    __u8  s_def_hash_version; /* Default hash version to use */
-+    __u8  s_jnl_backup_type;  /* Default type of journal backup */
-+    __u16 s_desc_size;                /* size of group descriptor */
-+    __u32 s_default_mount_opts;
-+    __u32 s_first_meta_bg;    /* First metablock group */
-+    __u32 s_mkfs_time;                /* When the filesystem was created */
-+    __u32 s_jnl_blocks[17];   /* Backup of the journal inode */
-+    __u32 s_reserved[172];    /* Padding to the end of the block */
-   };
--struct ext2_group_desc
-+struct ext4_group_desc
-   {
-     __u32 bg_block_bitmap;    /* Blocks bitmap block */
-     __u32 bg_inode_bitmap;    /* Inodes bitmap block */
-@@ -90,8 +136,18 @@
-     __u16 bg_free_blocks_count;       /* Free blocks count */
-     __u16 bg_free_inodes_count;       /* Free inodes count */
-     __u16 bg_used_dirs_count; /* Directories count */
--    __u16 bg_pad;
--    __u32 bg_reserved[3];
-+    __u16 bg_flags;           /* EXT4_BG_flags (INODE_UNINIT, etc) */
-+    __u32 bg_reserved[2];             /* Likely block/inode bitmap checksum */
-+    __u16 bg_itable_unused;   /* Unused inodes count */
-+    __u16 bg_checksum;                /* crc16(sb_uuid+group+desc) */
-+    __u32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
-+    __u32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
-+    __u32 bg_inode_table_hi;  /* Inodes table block MSB */
-+    __u16 bg_free_blocks_count_hi;/* Free blocks count MSB */
-+    __u16 bg_free_inodes_count_hi;/* Free inodes count MSB */
-+    __u16 bg_used_dirs_count_hi;      /* Directories count MSB */
-+    __u16 bg_itable_unused_hi;        /* Unused inodes count MSB */
-+    __u32 bg_reserved2[3];
-   };
- struct ext2_inode
-@@ -129,22 +185,22 @@
-     __u32 i_block[EXT2_N_BLOCKS];     /* 40: Pointers to blocks */
-     __u32 i_version;          /* File version (for NFS) */
-     __u32 i_file_acl;         /* File ACL */
--    __u32 i_dir_acl;          /* Directory ACL */
--    __u32 i_faddr;            /* Fragment address */
-+    __u32 i_size_high;
-+    __u32 i_obso_faddr;               /* Obsoleted fragment address */
-     union
-       {
-       struct
-         {
--          __u8 l_i_frag;      /* Fragment number */
--          __u8 l_i_fsize;     /* Fragment size */
--          __u16 i_pad1;
--          __u32 l_i_reserved2[2];
-+              __u16   l_i_blocks_high; /* were l_i_reserved1 */
-+              __u16   l_i_file_acl_high;
-+              __u16   l_i_uid_high;   /* these 2 fields */
-+              __u16   l_i_gid_high;   /* were reserved2[0] */
-+              __u32   l_i_reserved2;
-         }
-       linux2;
-       struct
-         {
--          __u8 h_i_frag;      /* Fragment number */
--          __u8 h_i_fsize;     /* Fragment size */
-+              __u16   h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
-           __u16 h_i_mode_high;
-           __u16 h_i_uid_high;
-           __u16 h_i_gid_high;
-@@ -153,16 +209,36 @@
-       hurd2;
-       struct
-         {
--          __u8 m_i_frag;      /* Fragment number */
--          __u8 m_i_fsize;     /* Fragment size */
--          __u16 m_pad1;
-+              __u16   h_i_reserved1;  /* Obsoleted fragment number/size which are removed in ext4 */
-+              __u16   m_i_file_acl_high;
-           __u32 m_i_reserved2[2];
-         }
-       masix2;
-       }
-     osd2;                     /* OS dependent 2 */
-+      __u16   i_extra_isize;
-+      __u16   i_pad1;
-+      __u32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
-+      __u32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */
-+      __u32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */
-+      __u32  i_crtime;       /* File Creation time */
-+      __u32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
-+      __u32  i_version_hi;    /* high 32 bits for 64-bit version */
-   };
-+#define EXT4_FEATURE_INCOMPAT_EXTENTS         0x0040 /* extents support */
-+#define EXT4_FEATURE_INCOMPAT_64BIT                   0x0080 /* grub not supported*/
-+#define EXT4_FEATURE_INCOMPAT_MMP           0x0100
-+#define EXT4_FEATURE_INCOMPAT_FLEX_BG         0x0200
-+
-+#define EXT4_HAS_INCOMPAT_FEATURE(sb,mask)                    \
-+      ( sb->s_feature_incompat & mask )
-+
-+#define EXT4_EXTENTS_FL               0x00080000 /* Inode uses extents */
-+#define EXT4_HUGE_FILE_FL     0x00040000 /* Set to each huge file */
-+
-+#define EXT4_MIN_DESC_SIZE                    32
-+
- /* linux/limits.h */
- #define NAME_MAX         255  /* # chars in a file name */
-@@ -180,6 +256,57 @@
-     char name[EXT2_NAME_LEN]; /* File name */
-   };
-+/* linux/ext4_fs_extents.h */ 
-+/* This is the extent on-disk structure.
-+ * It's used at the bottom of the tree.
-+ */
-+struct ext4_extent 
-+  {
-+      __u32  ee_block;   /* first logical block extent covers */
-+      __u16  ee_len;     /* number of blocks covered by extent */
-+      __u16  ee_start_hi;    /* high 16 bits of physical block */
-+      __u32  ee_start_lo;    /* low 32 bits of physical block */
-+  };
-+
-+/*
-+ * This is index on-disk structure.
-+ * It's used at all the levels except the bottom.
-+ */
-+struct ext4_extent_idx 
-+  {
-+    __u32  ei_block;   /* index covers logical blocks from 'block' */
-+    __u32  ei_leaf_lo; /* pointer to the physical block of the next *
-+                           * level. leaf or next index could be there */
-+    __u16  ei_leaf_hi; /* high 16 bits of physical block */
-+    __u16  ei_unused;
-+  };
-+
-+/*
-+ * Each block (leaves and indexes), even inode-stored has header.
-+ */
-+struct ext4_extent_header 
-+  {
-+    __u16  eh_magic;   /* probably will support different formats */
-+    __u16  eh_entries; /* number of valid entries */
-+    __u16  eh_max;     /* capacity of store in entries */
-+    __u16  eh_depth;   /* has tree real underlying blocks? */
-+    __u32  eh_generation;  /* generation of the tree */
-+  };
-+
-+#define EXT4_EXT_MAGIC      (0xf30a)
-+#define EXT_FIRST_EXTENT(__hdr__) \
-+    ((struct ext4_extent *) (((char *) (__hdr__)) +     \
-+                 sizeof(struct ext4_extent_header)))
-+#define EXT_FIRST_INDEX(__hdr__) \
-+    ((struct ext4_extent_idx *) (((char *) (__hdr__)) + \
-+                 sizeof(struct ext4_extent_header)))
-+#define EXT_LAST_EXTENT(__hdr__) \
-+    (EXT_FIRST_EXTENT((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1)
-+#define EXT_LAST_INDEX(__hdr__) \
-+    (EXT_FIRST_INDEX((__hdr__)) + (__u16)((__hdr__)->eh_entries) - 1)
-+
-+
-+
- /* linux/ext2fs.h */
- /*
-  * EXT2_DIR_PAD defines the directory entries boundaries
-@@ -218,13 +345,30 @@
- #define EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
- #define EXT2_ADDR_PER_BLOCK_BITS(s)           (log2(EXT2_ADDR_PER_BLOCK(s)))
-+#define EXT2_GOOD_OLD_REV     0       /* The good old (original) format */
-+#define EXT2_DYNAMIC_REV      1       /* V2 format w/ dynamic inode sizes */
-+#define EXT2_GOOD_OLD_INODE_SIZE 128
-+#define EXT2_INODE_SIZE(s)    (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
-+                              EXT2_GOOD_OLD_INODE_SIZE : \
-+                              (s)->s_inode_size)
-+#define EXT2_INODES_PER_BLOCK(s)      (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
-+
- /* linux/ext2_fs.h */
- #define EXT2_BLOCK_SIZE_BITS(s)        ((s)->s_log_block_size + 10)
- /* kind of from ext2/super.c */
- #define EXT2_BLOCK_SIZE(s)    (1 << EXT2_BLOCK_SIZE_BITS(s))
- /* linux/ext2fs.h */
-+/* sizeof(struct ext2_group_desc) is changed in ext4 
-+ * in kernel code, ext2/3 uses sizeof(struct ext2_group_desc) to calculate 
-+ * number of desc per block, while ext4 uses superblock->s_desc_size in stead
-+ * superblock->s_desc_size is not available in ext2/3
-+ * */
-+#define EXT2_DESC_SIZE(s) \
-+      (EXT4_HAS_INCOMPAT_FEATURE(s,EXT4_FEATURE_INCOMPAT_64BIT)? \
-+      s->s_desc_size : EXT4_MIN_DESC_SIZE)
- #define EXT2_DESC_PER_BLOCK(s) \
--     (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
-+      (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
-+
- /* linux/stat.h */
- #define S_IFMT  00170000
- #define S_IFLNK  0120000
-@@ -386,6 +530,122 @@
-     [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
- }
-+/* extent binary search index
-+ * find closest index in the current level extent tree
-+ * kind of from ext4_ext_binsearch_idx in ext4/extents.c
-+ */
-+static struct ext4_extent_idx*
-+ext4_ext_binsearch_idx(struct ext4_extent_header* eh, int logical_block)
-+{
-+  struct ext4_extent_idx *r, *l, *m;
-+  l = EXT_FIRST_INDEX(eh) + 1;
-+  r = EXT_LAST_INDEX(eh);
-+  while (l <= r) 
-+    {
-+        m = l + (r - l) / 2;
-+        if (logical_block < m->ei_block)
-+                r = m - 1;
-+        else
-+                l = m + 1;
-+      }
-+  return (struct ext4_extent_idx*)(l - 1);
-+}
-+
-+/* extent binary search 
-+ * find closest extent in the leaf level 
-+ * kind of from ext4_ext_binsearch in ext4/extents.c
-+ */
-+static struct ext4_extent*
-+ext4_ext_binsearch(struct ext4_extent_header* eh, int logical_block)
-+{
-+  struct ext4_extent *r, *l, *m;
-+  l = EXT_FIRST_EXTENT(eh) + 1;
-+  r = EXT_LAST_EXTENT(eh);
-+  while (l <= r) 
-+    {
-+        m = l + (r - l) / 2;
-+        if (logical_block < m->ee_block)
-+                r = m - 1;
-+        else
-+                l = m + 1;
-+      }
-+  return (struct ext4_extent*)(l - 1);
-+}
-+
-+/* Maps extents enabled logical block into physical block via an inode. 
-+ * EXT4_HUGE_FILE_FL should be checked before calling this.
-+ */
-+static int
-+ext4fs_block_map (int logical_block)
-+{
-+  struct ext4_extent_header *eh;
-+  struct ext4_extent *ex, *extent;
-+  struct ext4_extent_idx *ei, *index;
-+  int depth;
-+  int i;
-+
-+#ifdef E2DEBUG
-+  unsigned char *i;
-+  for (i = (unsigned char *) INODE;
-+       i < ((unsigned char *) INODE + sizeof (struct ext2_inode));
-+       i++)
-+    {
-+      printf ("%c", "0123456789abcdef"[*i >> 4]);
-+      printf ("%c", "0123456789abcdef"[*i % 16]);
-+      if (!((i + 1 - (unsigned char *) INODE) % 16))
-+      {
-+        printf ("\n");
-+      }
-+      else
-+      {
-+        printf (" ");
-+      }
-+    }
-+  printf ("logical block %d\n", logical_block);
-+#endif /* E2DEBUG */
-+  eh = (struct ext4_extent_header*)INODE->i_block;
-+  if (eh->eh_magic != EXT4_EXT_MAGIC)
-+  {
-+          errnum = ERR_FSYS_CORRUPT;
-+          return -1;
-+  }
-+  while((depth = eh->eh_depth) != 0)
-+      { /* extent index */
-+        if (eh->eh_magic != EXT4_EXT_MAGIC)
-+        {
-+                errnum = ERR_FSYS_CORRUPT;
-+                return -1;
-+        }
-+        ei = ext4_ext_binsearch_idx(eh, logical_block);
-+        if (ei->ei_leaf_hi)
-+      {/* 64bit physical block number not supported */
-+        errnum = ERR_FILELENGTH;
-+        return -1;
-+      }
-+        if (!ext2_rdfsb(ei->ei_leaf_lo, DATABLOCK1))
-+      {
-+        errnum = ERR_FSYS_CORRUPT;
-+        return -1;
-+      }
-+        eh = (struct ext4_extent_header*)DATABLOCK1;
-+      }
-+
-+  /* depth==0, we come to the leaf */
-+  ex = ext4_ext_binsearch(eh, logical_block);
-+  if (ex->ee_start_hi) 
-+      {/* 64bit physical block number not supported */
-+        errnum = ERR_FILELENGTH;
-+        return -1;
-+      }
-+  if ((ex->ee_block + ex->ee_len) < logical_block)
-+      {
-+        errnum = ERR_FSYS_CORRUPT;
-+        return -1;
-+      }
-+  return ex->ee_start_lo + logical_block - ex->ee_block;
-+
-+}
-+
- /* preconditions: all preconds of ext2fs_block_map */
- int
- ext2fs_read (char *buf, int len)
-@@ -420,6 +680,11 @@
-       /* find the (logical) block component of our location */
-       logical_block = filepos >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
-       offset = filepos & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1);
-+      /* map extents enabled logical block number to physical fs on-dick block number */
-+      if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS) 
-+                    && INODE->i_flags & EXT4_EXTENTS_FL)
-+          map = ext4fs_block_map (logical_block);
-+      else
-       map = ext2fs_block_map (logical_block);
- #ifdef E2DEBUG
-       printf ("map=%d\n", map);
-@@ -504,7 +769,7 @@
-   int desc;                   /* index within that group */
-   int ino_blk;                        /* fs pointer of the inode's information */
-   int str_chk = 0;            /* used to hold the results of a string compare */
--  struct ext2_group_desc *gdp;
-+  struct ext4_group_desc *ext4_gdp;
-   struct ext2_inode *raw_inode;       /* inode info corresponding to current_ino */
-   char linkbuf[PATH_MAX];     /* buffer for following symbolic links */
-@@ -550,10 +815,17 @@
-       {
-         return 0;
-       }
--      gdp = GROUP_DESC;
--      ino_blk = gdp[desc].bg_inode_table +
-+        ext4_gdp = (struct ext4_group_desc *)( (__u8*)GROUP_DESC + 
-+                                      desc * EXT2_DESC_SIZE(SUPERBLOCK));
-+        if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK, EXT4_FEATURE_INCOMPAT_64BIT)
-+              && (! ext4_gdp->bg_inode_table_hi))
-+      {/* 64bit itable not supported */
-+        errnum = ERR_FILELENGTH;
-+        return -1;
-+      }
-+      ino_blk = ext4_gdp->bg_inode_table + 
-       (((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
--       >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
-+       >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
- #ifdef E2DEBUG
-       printf ("inode table fsblock=%d\n", ino_blk);
- #endif /* E2DEBUG */
-@@ -565,13 +837,12 @@
-       /* reset indirect blocks! */
-       mapblock2 = mapblock1 = -1;
--      raw_inode = INODE +
--      ((current_ino - 1)
--       & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
-+      raw_inode = (struct ext2_inode *)((char *)INODE +
-+      ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *
-+      EXT2_INODE_SIZE (SUPERBLOCK));
- #ifdef E2DEBUG
-       printf ("ipb=%d, sizeof(inode)=%d\n",
--            (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
--            sizeof (struct ext2_inode));
-+            EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
-       printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
-       printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
-       for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;
-@@ -629,7 +900,10 @@
-           }
-         linkbuf[filemax + len] = '\0';
--        /* Read the symlink data. */
-+        /* Read the symlink data. 
-+         * Slow symlink is extents enabled
-+         * But since grub_read invokes ext2fs_read, nothing to change here
-+         * */
-         if (! ext2_is_fast_symlink ())
-           {
-             /* Read the necessary blocks, and reset the file pointer. */
-@@ -640,7 +914,9 @@
-           }
-         else
-           {
--            /* Copy the data directly from the inode. */
-+            /* Copy the data directly from the inode. 
-+                 * Fast symlink is not extents enabled
-+                 * */
-             len = filemax;
-             memmove (linkbuf, (char *) INODE->i_block, len);
-           }
-@@ -674,6 +950,13 @@
-             errnum = ERR_BAD_FILETYPE;
-             return 0;
-           }
-+        /* if file is too large, just stop and report an error*/
-+        if ( (INODE->i_flags & EXT4_HUGE_FILE_FL) && !(INODE->i_size_high))
-+          {
-+                /* file too large, stop reading */
-+                errnum = ERR_FILELENGTH;
-+                return 0;
-+          }
-         filemax = (INODE->i_size);
-         return 1;
-@@ -728,17 +1011,28 @@
-           }
-         /* else, find the (logical) block component of our location */
-+        /* ext4 logical block number the same as ext2/3 */
-         blk = loc >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
-         /* we know which logical block of the directory entry we are looking
-            for, now we have to translate that to the physical (fs) block on
-            the disk */
-+        /* map extents enabled logical block number to physical fs on-dick block number */
-+        if (EXT4_HAS_INCOMPAT_FEATURE(SUPERBLOCK,EXT4_FEATURE_INCOMPAT_EXTENTS) 
-+                        && INODE->i_flags & EXT4_EXTENTS_FL)
-+              map = ext4fs_block_map (blk);
-+        else
-         map = ext2fs_block_map (blk);
- #ifdef E2DEBUG
-         printf ("fs block=%d\n", map);
- #endif /* E2DEBUG */
-         mapblock2 = -1;
--        if ((map < 0) || !ext2_rdfsb (map, DATABLOCK2))
-+        if (map < 0) 
-+        {
-+            *rest = ch;
-+            return 0;
-+        }
-+          if (!ext2_rdfsb (map, DATABLOCK2))
-           {
-             errnum = ERR_FSYS_CORRUPT;
-             *rest = ch;
-diff -Nur grub-0.97/stage2/gpt.h grub-0.97-patched/stage2/gpt.h
---- grub-0.97/stage2/gpt.h     1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/stage2/gpt.h     2012-11-11 17:07:12.697728638 +0100
-@@ -0,0 +1,68 @@
-+/*
-+ *  GRUB  --  GRand Unified Bootloader
-+ *  Copyright (C) 2002,2005,2006   Free Software Foundation, Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#ifndef _GPT_H
-+#define _GPT_H
-+
-+typedef signed char grub_int8_t;
-+typedef signed short grub_int16_t;
-+typedef signed int grub_int32_t;
-+typedef signed long long int grub_int64_t;
-+typedef unsigned char grub_uint8_t;
-+typedef unsigned short grub_uint16_t;
-+typedef unsigned int grub_uint32_t;
-+typedef unsigned long long int grub_uint64_t;
-+
-+struct grub_gpt_header
-+{
-+  grub_uint64_t magic;
-+  grub_uint32_t version;
-+  grub_uint32_t headersize;
-+  grub_uint32_t crc32;
-+  grub_uint32_t unused1;
-+  grub_uint64_t primary;
-+  grub_uint64_t backup;
-+  grub_uint64_t start;
-+  grub_uint64_t end;
-+  grub_uint8_t guid[16];
-+  grub_uint64_t partitions;
-+  grub_uint32_t maxpart;
-+  grub_uint32_t partentry_size;
-+  grub_uint32_t partentry_crc32;
-+} __attribute__ ((packed));
-+
-+struct grub_gpt_partentry
-+{
-+  grub_uint64_t type1;
-+  grub_uint64_t type2;
-+  grub_uint8_t guid[16];
-+  grub_uint64_t start;
-+  grub_uint64_t end;
-+  grub_uint8_t attrib;
-+  char name[72];
-+} __attribute__ ((packed));
-+
-+#define GPT_HEADER_MAGIC       0x5452415020494645UL
-+
-+#define        GPT_ENTRY_SECTOR(size,entry)                                    \
-+       ((((entry) * (size) + 1) & ~(SECTOR_SIZE - 1)) >> SECTOR_BITS)
-+#define        GPT_ENTRY_INDEX(size,entry)                                     \
-+       ((((entry) * (size) + 1) & (SECTOR_SIZE - 1)) - 1)
-+
-+#endif /* _GPT_H */
-diff -Nur grub-0.97/stage2/graphics.c grub-0.97-patched/stage2/graphics.c
---- grub-0.97/stage2/graphics.c        1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/stage2/graphics.c        2012-11-11 17:06:33.320470847 +0100
-@@ -0,0 +1,563 @@
-+/* graphics.c - graphics mode support for GRUB */
-+/* Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based
-+ * on a patch by Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
-+ */
-+/*
-+ *  GRUB  --  GRand Unified Bootloader
-+ *  Copyright (C) 2001,2002  Red Hat, Inc.
-+ *  Portions copyright (C) 2000  Conectiva, Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+
-+
-+#ifdef SUPPORT_GRAPHICS
-+
-+#include <term.h>
-+#include <shared.h>
-+#include <graphics.h>
-+
-+int saved_videomode;
-+unsigned char *font8x16;
-+
-+int graphics_inited = 0;
-+static char splashimage[64];
-+
-+#define VSHADOW VSHADOW1
-+unsigned char VSHADOW1[38400];
-+unsigned char VSHADOW2[38400];
-+unsigned char VSHADOW4[38400];
-+unsigned char VSHADOW8[38400];
-+
-+/* constants to define the viewable area */
-+const int x0 = 0;
-+const int x1 = 80;
-+const int y0 = 0;
-+const int y1 = 30;
-+
-+/* text buffer has to be kept around so that we can write things as we
-+ * scroll and the like */
-+unsigned short text[80 * 30];
-+
-+/* why do these have to be kept here? */
-+int foreground = (63 << 16) | (63 << 8) | (63), background = 0, border = 0;
-+
-+/* current position */
-+static int fontx = 0;
-+static int fonty = 0;
-+
-+/* global state so that we don't try to recursively scroll or cursor */
-+static int no_scroll = 0;
-+
-+/* color state */
-+static int graphics_standard_color = A_NORMAL;
-+static int graphics_normal_color = A_NORMAL;
-+static int graphics_highlight_color = A_REVERSE;
-+static int graphics_current_color = A_NORMAL;
-+static color_state graphics_color_state = COLOR_STATE_STANDARD;
-+
-+
-+/* graphics local functions */
-+static void graphics_setxy(int col, int row);
-+static void graphics_scroll();
-+
-+/* FIXME: where do these really belong? */
-+static inline void outb(unsigned short port, unsigned char val)
-+{
-+    __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
-+}
-+
-+static void MapMask(int value) {
-+    outb(0x3c4, 2);
-+    outb(0x3c5, value);
-+}
-+
-+/* bit mask register */
-+static void BitMask(int value) {
-+    outb(0x3ce, 8);
-+    outb(0x3cf, value);
-+}
-+
-+
-+
-+/* Set the splash image */
-+void graphics_set_splash(char *splashfile) {
-+    grub_strcpy(splashimage, splashfile);
-+}
-+
-+/* Get the current splash image */
-+char *graphics_get_splash(void) {
-+    return splashimage;
-+}
-+
-+/* Initialize a vga16 graphics display with the palette based off of
-+ * the image in splashimage.  If the image doesn't exist, leave graphics
-+ * mode.  */
-+int graphics_init()
-+{
-+    if(!grub_file_exists(splashimage)) {
-+        return 0;
-+    }
-+
-+    if (!graphics_inited) {
-+        saved_videomode = set_videomode(0x12);
-+    }
-+
-+    if (!read_image(splashimage)) {
-+        set_videomode(saved_videomode);
-+        grub_printf("failed to read image\n");
-+        return 0;
-+    }
-+
-+    font8x16 = (unsigned char*)graphics_get_font();
-+
-+    graphics_inited = 1;
-+
-+    /* make sure that the highlight color is set correctly */
-+    graphics_highlight_color = ((graphics_normal_color >> 4) | 
-+                              ((graphics_normal_color & 0xf) << 4));
-+
-+    return 1;
-+}
-+
-+/* Leave graphics mode */
-+void graphics_end(void)
-+{
-+    if (graphics_inited) {
-+        set_videomode(saved_videomode);
-+        graphics_inited = 0;
-+    }
-+}
-+
-+/* Print ch on the screen.  Handle any needed scrolling or the like */
-+void graphics_putchar(int ch) {
-+    ch &= 0xff;
-+
-+    graphics_cursor(0);
-+
-+    if (ch == '\n') {
-+        if (fonty + 1 < y1)
-+            graphics_setxy(fontx, fonty + 1);
-+        else
-+            graphics_scroll();
-+        graphics_cursor(1);
-+        return;
-+    } else if (ch == '\r') {
-+        graphics_setxy(x0, fonty);
-+        graphics_cursor(1);
-+        return;
-+    }
-+
-+    graphics_cursor(0);
-+
-+    text[fonty * 80 + fontx] = ch;
-+    text[fonty * 80 + fontx] &= 0x00ff;
-+    if (graphics_current_color & 0xf0)
-+        text[fonty * 80 + fontx] |= 0x100;
-+
-+    graphics_cursor(0);
-+
-+    if ((fontx + 1) >= x1) {
-+        graphics_setxy(x0, fonty);
-+        if (fonty + 1 < y1)
-+            graphics_setxy(x0, fonty + 1);
-+        else
-+            graphics_scroll();
-+    } else {
-+        graphics_setxy(fontx + 1, fonty);
-+    }
-+
-+    graphics_cursor(1);
-+}
-+
-+/* get the current location of the cursor */
-+int graphics_getxy(void) {
-+    return (fontx << 8) | fonty;
-+}
-+
-+void graphics_gotoxy(int x, int y) {
-+    graphics_cursor(0);
-+
-+    graphics_setxy(x, y);
-+
-+    graphics_cursor(1);
-+}
-+
-+void graphics_cls(void) {
-+    int i;
-+    unsigned char *mem, *s1, *s2, *s4, *s8;
-+
-+    graphics_cursor(0);
-+    graphics_gotoxy(x0, y0);
-+
-+    mem = (unsigned char*)VIDEOMEM;
-+    s1 = (unsigned char*)VSHADOW1;
-+    s2 = (unsigned char*)VSHADOW2;
-+    s4 = (unsigned char*)VSHADOW4;
-+    s8 = (unsigned char*)VSHADOW8;
-+
-+    for (i = 0; i < 80 * 30; i++)
-+        text[i] = ' ';
-+    graphics_cursor(1);
-+
-+    BitMask(0xff);
-+
-+    /* plano 1 */
-+    MapMask(1);
-+    grub_memcpy(mem, s1, 38400);
-+
-+    /* plano 2 */
-+    MapMask(2);
-+    grub_memcpy(mem, s2, 38400);
-+
-+    /* plano 3 */
-+    MapMask(4);
-+    grub_memcpy(mem, s4, 38400);
-+
-+    /* plano 4 */
-+    MapMask(8);
-+    grub_memcpy(mem, s8, 38400);
-+
-+    MapMask(15);
-+ 
-+}
-+
-+void graphics_setcolorstate (color_state state) {
-+    switch (state) {
-+    case COLOR_STATE_STANDARD:
-+        graphics_current_color = graphics_standard_color;
-+        break;
-+    case COLOR_STATE_NORMAL:
-+        graphics_current_color = graphics_normal_color;
-+        break;
-+    case COLOR_STATE_HIGHLIGHT:
-+        graphics_current_color = graphics_highlight_color;
-+        break;
-+    default:
-+        graphics_current_color = graphics_standard_color;
-+        break;
-+    }
-+
-+    graphics_color_state = state;
-+}
-+
-+void graphics_setcolor (int normal_color, int highlight_color) {
-+    graphics_normal_color = normal_color;
-+    graphics_highlight_color = highlight_color;
-+
-+    graphics_setcolorstate (graphics_color_state);
-+}
-+
-+void graphics_setcursor (int on) {
-+    /* FIXME: we don't have a cursor in graphics */
-+    return;
-+}
-+
-+/* Read in the splashscreen image and set the palette up appropriately.
-+ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
-+ * 640x480. */
-+int read_image(char *s)
-+{
-+    char buf[32], pal[16];
-+    unsigned char c, base, mask, *s1, *s2, *s4, *s8;
-+    unsigned i, len, idx, colors, x, y, width, height;
-+
-+    if (!grub_open(s))
-+        return 0;
-+
-+    /* read header */
-+    if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
-+        grub_close();
-+        return 0;
-+    }
-+    
-+    /* parse info */
-+    while (grub_read(&c, 1)) {
-+        if (c == '"')
-+            break;
-+    }
-+
-+    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
-+        ;
-+
-+    i = 0;
-+    width = c - '0';
-+    while (grub_read(&c, 1)) {
-+        if (c >= '0' && c <= '9')
-+            width = width * 10 + c - '0';
-+        else
-+            break;
-+    }
-+    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
-+        ;
-+
-+    height = c - '0';
-+    while (grub_read(&c, 1)) {
-+        if (c >= '0' && c <= '9')
-+            height = height * 10 + c - '0';
-+        else
-+            break;
-+    }
-+    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
-+        ;
-+
-+    colors = c - '0';
-+    while (grub_read(&c, 1)) {
-+        if (c >= '0' && c <= '9')
-+            colors = colors * 10 + c - '0';
-+        else
-+            break;
-+    }
-+
-+    base = 0;
-+    while (grub_read(&c, 1) && c != '"')
-+        ;
-+
-+    /* palette */
-+    for (i = 0, idx = 1; i < colors; i++) {
-+        len = 0;
-+
-+        while (grub_read(&c, 1) && c != '"')
-+            ;
-+        grub_read(&c, 1);       /* char */
-+        base = c;
-+        grub_read(buf, 4);      /* \t c # */
-+
-+        while (grub_read(&c, 1) && c != '"') {
-+            if (len < sizeof(buf))
-+                buf[len++] = c;
-+        }
-+
-+        if (len == 6 && idx < 15) {
-+            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
-+            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
-+            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
-+
-+            pal[idx] = base;
-+            graphics_set_palette(idx, r, g, b);
-+            ++idx;
-+        }
-+    }
-+
-+    x = y = len = 0;
-+
-+    s1 = (unsigned char*)VSHADOW1;
-+    s2 = (unsigned char*)VSHADOW2;
-+    s4 = (unsigned char*)VSHADOW4;
-+    s8 = (unsigned char*)VSHADOW8;
-+
-+    for (i = 0; i < 38400; i++)
-+        s1[i] = s2[i] = s4[i] = s8[i] = 0;
-+
-+    /* parse xpm data */
-+    while (y < height) {
-+        while (1) {
-+            if (!grub_read(&c, 1)) {
-+                grub_close();
-+                return 0;
-+            }
-+            if (c == '"')
-+                break;
-+        }
-+
-+        while (grub_read(&c, 1) && c != '"') {
-+            for (i = 1; i < 15; i++)
-+                if (pal[i] == c) {
-+                    c = i;
-+                    break;
-+                }
-+
-+            mask = 0x80 >> (x & 7);
-+            if (c & 1)
-+                s1[len + (x >> 3)] |= mask;
-+            if (c & 2)
-+                s2[len + (x >> 3)] |= mask;
-+            if (c & 4)
-+                s4[len + (x >> 3)] |= mask;
-+            if (c & 8)
-+                s8[len + (x >> 3)] |= mask;
-+
-+            if (++x >= 640) {
-+                x = 0;
-+
-+                if (y < 480)
-+                    len += 80;
-+                ++y;
-+            }
-+        }
-+    }
-+
-+    grub_close();
-+
-+    graphics_set_palette(0, (background >> 16), (background >> 8) & 63, 
-+                background & 63);
-+    graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, 
-+                foreground & 63);
-+    graphics_set_palette(0x11, (border >> 16), (border >> 8) & 63, 
-+                         border & 63);
-+
-+    return 1;
-+}
-+
-+
-+/* Convert a character which is a hex digit to the appropriate integer */
-+int hex(int v)
-+{
-+    if (v >= 'A' && v <= 'F')
-+        return (v - 'A' + 10);
-+    if (v >= 'a' && v <= 'f')
-+        return (v - 'a' + 10);
-+    return (v - '0');
-+}
-+
-+
-+/* move the graphics cursor location to col, row */
-+static void graphics_setxy(int col, int row) {
-+    if (col >= x0 && col < x1) {
-+        fontx = col;
-+        cursorX = col << 3;
-+    }
-+    if (row >= y0 && row < y1) {
-+        fonty = row;
-+        cursorY = row << 4;
-+    }
-+}
-+
-+/* scroll the screen */
-+static void graphics_scroll() {
-+    int i, j;
-+
-+    /* we don't want to scroll recursively... that would be bad */
-+    if (no_scroll)
-+        return;
-+    no_scroll = 1;
-+
-+    /* move everything up a line */
-+    for (j = y0 + 1; j < y1; j++) {
-+        graphics_gotoxy(x0, j - 1);
-+        for (i = x0; i < x1; i++) {
-+            graphics_putchar(text[j * 80 + i]);
-+        }
-+    }
-+
-+    /* last line should be blank */
-+    graphics_gotoxy(x0, y1 - 1);
-+    for (i = x0; i < x1; i++)
-+        graphics_putchar(' ');
-+    graphics_setxy(x0, y1 - 1);
-+
-+    no_scroll = 0;
-+}
-+
-+
-+void graphics_cursor(int set) {
-+    unsigned char *pat, *mem, *ptr, chr[16 << 2];
-+    int i, ch, invert, offset;
-+
-+    if (set && no_scroll)
-+        return;
-+
-+    offset = cursorY * 80 + fontx;
-+    ch = text[fonty * 80 + fontx] & 0xff;
-+    invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
-+    pat = font8x16 + (ch << 4);
-+
-+    mem = (unsigned char*)VIDEOMEM + offset;
-+
-+    if (!set) {
-+        for (i = 0; i < 16; i++) {
-+            unsigned char mask = pat[i];
-+
-+            if (!invert) {
-+                chr[i     ] = ((unsigned char*)VSHADOW1)[offset];
-+                chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
-+                chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
-+                chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
-+
-+                /* FIXME: if (shade) */
-+                if (1) {
-+                    if (ch == DISP_VERT || ch == DISP_LL ||
-+                        ch == DISP_UR || ch == DISP_LR) {
-+                        unsigned char pmask = ~(pat[i] >> 1);
-+
-+                        chr[i     ] &= pmask;
-+                        chr[16 + i] &= pmask;
-+                        chr[32 + i] &= pmask;
-+                        chr[48 + i] &= pmask;
-+                    }
-+                    if (i > 0 && ch != DISP_VERT) {
-+                        unsigned char pmask = ~(pat[i - 1] >> 1);
-+
-+                        chr[i     ] &= pmask;
-+                        chr[16 + i] &= pmask;
-+                        chr[32 + i] &= pmask;
-+                        chr[48 + i] &= pmask;
-+                        if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
-+                            pmask = ~pat[i - 1];
-+
-+                            chr[i     ] &= pmask;
-+                            chr[16 + i] &= pmask;
-+                            chr[32 + i] &= pmask;
-+                            chr[48 + i] &= pmask;
-+                        }
-+                    }
-+                }
-+                chr[i     ] |= mask;
-+                chr[16 + i] |= mask;
-+                chr[32 + i] |= mask;
-+                chr[48 + i] |= mask;
-+
-+                offset += 80;
-+            }
-+            else {
-+                chr[i     ] = mask;
-+                chr[16 + i] = mask;
-+                chr[32 + i] = mask;
-+                chr[48 + i] = mask;
-+            }
-+        }
-+    }
-+    else {
-+        MapMask(15);
-+        ptr = mem;
-+        for (i = 0; i < 16; i++, ptr += 80) {
-+            cursorBuf[i] = pat[i];
-+            *ptr = ~pat[i];
-+        }
-+        return;
-+    }
-+
-+    offset = 0;
-+    for (i = 1; i < 16; i <<= 1, offset += 16) {
-+        int j;
-+
-+        MapMask(i);
-+        ptr = mem;
-+        for (j = 0; j < 16; j++, ptr += 80)
-+            *ptr = chr[j + offset];
-+    }
-+
-+    MapMask(15);
-+}
-+
-+int grub_file_exists(char *s) {
-+    if (!grub_open(s))
-+        return 0;
-+    grub_close();
-+    return 1;
-+}
-+
-+#endif /* SUPPORT_GRAPHICS */
-diff -Nur grub-0.97/stage2/graphics.h grub-0.97-patched/stage2/graphics.h
---- grub-0.97/stage2/graphics.h        1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/stage2/graphics.h        2012-11-11 17:06:33.321470879 +0100
-@@ -0,0 +1,45 @@
-+/* graphics.h - graphics console interface */
-+/*
-+ *  GRUB  --  GRand Unified Bootloader
-+ *  Copyright (C) 2002  Free Software Foundation, Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#ifndef GRAPHICS_H
-+#define GRAPHICS_H
-+
-+/* magic constant */
-+#define VIDEOMEM 0xA0000
-+
-+/* function prototypes */
-+char *graphics_get_splash(void);
-+
-+int read_image(char *s);
-+void graphics_cursor(int set);
-+
-+/* function prototypes for asm functions */
-+void * graphics_get_font();
-+void graphics_set_palette(int idx, int red, int green, int blue);
-+void set_int1c_handler();
-+void unset_int1c_handler();
-+
-+/* Only to check for safe opening before we start */
-+int grub_file_exists(char *s);
-+
-+extern short cursorX, cursorY;
-+extern char cursorBuf[16];
-+
-+#endif /* GRAPHICS_H */
-diff -Nur grub-0.97/stage2/iso9660.h grub-0.97-patched/stage2/iso9660.h
---- grub-0.97/stage2/iso9660.h 2004-03-27 17:02:38.000000000 +0100
-+++ grub-0.97-patched/stage2/iso9660.h 2012-11-11 17:07:12.740730013 +0100
-@@ -73,11 +73,11 @@
- typedef       struct __iso_16bit {
-   u_int16_t l, b;
--} iso_16bit_t __attribute__ ((packed));
-+} iso_16bit_t;
- typedef       struct __iso_32bit {
-   u_int32_t l, b;
--} iso_32bit_t __attribute__ ((packed));
-+} iso_32bit_t;
- typedef u_int8_t              iso_date_t[7];
-diff -Nur grub-0.97/stage2/Makefile.am grub-0.97-patched/stage2/Makefile.am
---- grub-0.97/stage2/Makefile.am       2005-02-02 21:37:35.000000000 +0100
-+++ grub-0.97-patched/stage2/Makefile.am       2012-11-11 17:07:12.747730236 +0100
-@@ -7,7 +7,7 @@
-         fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
-       imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
-       nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
--      terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
-+      terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
- EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
- # For <stage1.h>.
-@@ -19,20 +19,20 @@
-       disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
-       fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
-       fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
--      terminfo.c tparm.c
--libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
-+      terminfo.c tparm.c graphics.c
-+libgrub_a_CFLAGS = $(GRUB_CFLAGS) -fno-stack-protector -I$(top_srcdir)/lib \
-       -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
-       -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
-       -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
-       -DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1
- # Stage 2 and Stage 1.5's.
--pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
-+stagedir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
- EXTRA_PROGRAMS = nbloader.exec pxeloader.exec diskless.exec
- if DISKLESS_SUPPORT
--pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
-+stage_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
-       ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
-       reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \
-       nbgrub pxegrub
-@@ -43,7 +43,7 @@
-       reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
-       xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec
- else
--pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
-+stage_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
-       ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
-       reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5
- noinst_DATA = pre_stage2 start start_eltorito
-@@ -79,8 +79,14 @@
- HERCULES_FLAGS =
- endif
--STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
--      $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
-+if GRAPHICS_SUPPORT
-+GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
-+else
-+GRAPHICS_FLAGS =
-+endif
-+
-+STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-reorder-functions -fno-builtin -nostdinc \
-+      $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
- STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
- STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
-@@ -90,7 +96,8 @@
-       cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
-       fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
-       fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
--      hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
-+      hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
-+      graphics.c
- pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
- pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
- pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
-@@ -105,7 +112,7 @@
- BUILT_SOURCES = stage2_size.h
- endif
--CLEANFILES = $(pkglib_DATA) $(noinst_DATA) $(BUILT_SOURCES)
-+CLEANFILES = $(stage_DATA) $(noinst_DATA) $(BUILT_SOURCES)
- stage2_size.h: pre_stage2
-       -rm -f stage2_size.h
-diff -Nur grub-0.97/stage2/Makefile.am.orig grub-0.97-patched/stage2/Makefile.am.orig
---- grub-0.97/stage2/Makefile.am.orig  1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/stage2/Makefile.am.orig  2005-02-02 21:37:35.000000000 +0100
-@@ -0,0 +1,272 @@
-+# For test target.
-+TESTS = size_test
-+noinst_SCRIPTS = $(TESTS)
-+
-+# For dist target.
-+noinst_HEADERS = apic.h defs.h dir.h disk_inode.h disk_inode_ffs.h \
-+        fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
-+      imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
-+      nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
-+      terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
-+EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
-+
-+# For <stage1.h>.
-+INCLUDES = -I$(top_srcdir)/stage1
-+
-+# The library for /sbin/grub.
-+noinst_LIBRARIES = libgrub.a
-+libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \
-+      disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
-+      fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
-+      fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
-+      terminfo.c tparm.c
-+libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
-+      -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
-+      -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
-+      -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
-+      -DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1
-+
-+# Stage 2 and Stage 1.5's.
-+pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
-+
-+EXTRA_PROGRAMS = nbloader.exec pxeloader.exec diskless.exec
-+
-+if DISKLESS_SUPPORT
-+pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
-+      ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
-+      reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \
-+      nbgrub pxegrub
-+noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless
-+noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
-+      e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
-+      iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
-+      reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
-+      xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec
-+else
-+pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
-+      ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
-+      reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5
-+noinst_DATA = pre_stage2 start start_eltorito
-+noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
-+      e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
-+      iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
-+      reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
-+      xfs_stage1_5.exec
-+endif
-+MOSTLYCLEANFILES = $(noinst_PROGRAMS)
-+
-+PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200
-+START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000
-+NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0
-+PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
-+START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
-+
-+if NETBOOT_SUPPORT
-+NETBOOT_FLAGS = -I$(top_srcdir)/netboot -DSUPPORT_NETBOOT=1
-+else
-+NETBOOT_FLAGS =
-+endif
-+
-+if SERIAL_SUPPORT
-+SERIAL_FLAGS = -DSUPPORT_SERIAL=1
-+else
-+SERIAL_FLAGS =
-+endif
-+
-+if HERCULES_SUPPORT
-+HERCULES_FLAGS = -DSUPPORT_HERCULES=1
-+else
-+HERCULES_FLAGS =
-+endif
-+
-+STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
-+      $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
-+
-+STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
-+STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
-+
-+# For stage2 target.
-+pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
-+      cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
-+      fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
-+      fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
-+      hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
-+pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
-+pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
-+pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
-+
-+if NETBOOT_SUPPORT
-+pre_stage2_exec_LDADD = ../netboot/libdrivers.a
-+endif
-+
-+if DISKLESS_SUPPORT
-+BUILT_SOURCES = stage2_size.h diskless_size.h
-+else
-+BUILT_SOURCES = stage2_size.h
-+endif
-+
-+CLEANFILES = $(pkglib_DATA) $(noinst_DATA) $(BUILT_SOURCES)
-+
-+stage2_size.h: pre_stage2
-+      -rm -f stage2_size.h
-+      set dummy `ls -l pre_stage2`; \
-+      echo "#define STAGE2_SIZE $$6" > stage2_size.h
-+
-+start_exec_SOURCES = start.S
-+start_exec_CCASFLAGS = $(STAGE2_COMPILE)
-+start_exec_LDFLAGS = $(START_LINK)
-+
-+# XXX: automake doesn't provide a way to specify dependencies for object
-+# files explicitly, so we must write this by a general Makefile scheme.
-+# If automake change the naming scheme for per-executable objects, this
-+# will be broken.
-+start_exec-start.$(OBJEXT): stage2_size.h
-+
-+stage2: pre_stage2 start
-+      -rm -f stage2
-+      cat start pre_stage2 > stage2
-+
-+start_eltorito_exec_SOURCES = start_eltorito.S
-+start_eltorito_exec_CCASFLAGS = $(STAGE2_COMPILE)
-+start_eltorito_exec_LDFLAGS = $(START_ELTORITO_LINK)
-+
-+start_eltorito_exec-start.$(OBJEXT): stage2_size.h
-+
-+stage2_eltorito: pre_stage2 start_eltorito
-+      -rm -f stage2_eltorito
-+      cat start_eltorito pre_stage2 > stage2_eltorito
-+
-+# For e2fs_stage1_5 target.
-+e2fs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
-+      stage1_5.c fsys_ext2fs.c bios.c
-+e2fs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_EXT2FS=1 \
-+      -DNO_BLOCK_FILES=1
-+e2fs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_EXT2FS=1 \
-+      -DNO_BLOCK_FILES=1
-+e2fs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For fat_stage1_5 target.
-+fat_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
-+      stage1_5.c fsys_fat.c bios.c
-+fat_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FAT=1 \
-+      -DNO_BLOCK_FILES=1
-+fat_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FAT=1 \
-+      -DNO_BLOCK_FILES=1
-+fat_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For ffs_stage1_5 target.
-+ffs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
-+      stage1_5.c fsys_ffs.c bios.c
-+ffs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \
-+      -DNO_BLOCK_FILES=1
-+ffs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \
-+      -DNO_BLOCK_FILES=1
-+ffs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For ufs2_stage1_5 target.
-+ufs2_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
-+      stage1_5.c fsys_ufs2.c bios.c
-+ufs2_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
-+      -DNO_BLOCK_FILES=1
-+ufs2_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
-+      -DNO_BLOCK_FILES=1
-+ufs2_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For minix_stage1_5 target.
-+minix_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
-+      stage1_5.c fsys_minix.c bios.c
-+minix_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_MINIX=1 \
-+      -DNO_BLOCK_FILES=1
-+minix_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_MINIX=1 \
-+      -DNO_BLOCK_FILES=1
-+minix_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For reiserfs_stage1_5 target.
-+reiserfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
-+      disk_io.c stage1_5.c fsys_reiserfs.c bios.c
-+reiserfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_REISERFS=1 \
-+      -DNO_BLOCK_FILES=1
-+reiserfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_REISERFS=1 \
-+      -DNO_BLOCK_FILES=1
-+reiserfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For vstafs_stage1_5 target.
-+vstafs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
-+      disk_io.c stage1_5.c fsys_vstafs.c bios.c
-+vstafs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_VSTAFS=1 \
-+      -DNO_BLOCK_FILES=1
-+vstafs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_VSTAFS=1 \
-+      -DNO_BLOCK_FILES=1
-+vstafs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For jfs_stage1_5 target.
-+jfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
-+      disk_io.c stage1_5.c fsys_jfs.c bios.c
-+jfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_JFS=1 \
-+      -DNO_BLOCK_FILES=1
-+jfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_JFS=1 \
-+      -DNO_BLOCK_FILES=1
-+jfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For xfs_stage1_5 target.
-+xfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
-+      disk_io.c stage1_5.c fsys_xfs.c bios.c
-+xfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_XFS=1 \
-+      -DNO_BLOCK_FILES=1
-+xfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_XFS=1 \
-+      -DNO_BLOCK_FILES=1
-+xfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For iso9660_stage1_5 target.
-+iso9660_stage1_5_exec_SOURCES = start_eltorito.S asm.S common.c char_io.c \
-+      disk_io.c stage1_5.c fsys_iso9660.c bios.c
-+iso9660_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ISO9660=1 \
-+      -DNO_BLOCK_FILES=1
-+iso9660_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ISO9660=1 \
-+      -DNO_BLOCK_FILES=1
-+iso9660_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
-+
-+# For diskless target.
-+diskless_exec_SOURCES = $(pre_stage2_exec_SOURCES)
-+diskless_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \
-+      -DSUPPORT_DISKLESS=1
-+diskless_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \
-+      -DSUPPORT_DISKLESS=1
-+diskless_exec_LDFLAGS = $(PRE_STAGE2_LINK)
-+diskless_exec_LDADD = ../netboot/libdrivers.a
-+
-+diskless_size.h: diskless
-+      -rm -f $@
-+      set dummy `ls -l $^`; \
-+      echo "#define DISKLESS_SIZE $$6" > $@
-+
-+# For nbloader target.
-+nbloader_exec_SOURCES = nbloader.S
-+nbloader_exec_CCASFLAGS = $(STAGE2_COMPILE)
-+nbloader_exec_LDFLAGS = $(NBLOADER_LINK)
-+
-+# XXX: See the comment for start_exec-start.o.
-+nbloader_exec-nbloader.$(OBJEXT): diskless_size.h
-+
-+# For nbgrub target.
-+nbgrub: nbloader diskless
-+      -rm -f $@
-+      cat $^ > $@
-+
-+# For pxeloader target.
-+pxeloader_exec_SOURCES = pxeloader.S
-+pxeloader_exec_CCASFLAGS = $(STAGE2_COMPILE)
-+pxeloader_exec_LDFLAGS = $(PXELOADER_LINK)
-+
-+# XXX: See the comment for start_exec-start.o.
-+pxeloader_exec-pxeloader.$(OBJEXT): diskless_size.h
-+
-+# For pxegrub target.
-+pxegrub: pxeloader diskless
-+      -rm -f $@
-+      cat $^ > $@
-+
-+# General rule for making a raw binary.
-+SUFFIXES = .exec
-+.exec:
-+      $(OBJCOPY) -O binary $< $@
-diff -Nur grub-0.97/stage2/pc_slice.h grub-0.97-patched/stage2/pc_slice.h
---- grub-0.97/stage2/pc_slice.h        2003-07-09 13:45:53.000000000 +0200
-+++ grub-0.97-patched/stage2/pc_slice.h        2012-11-11 17:07:12.698728671 +0100
-@@ -115,6 +115,7 @@
- #define PC_SLICE_TYPE_LINUX_EXTENDED  0x85
- #define PC_SLICE_TYPE_VSTAFS          0x9e
- #define PC_SLICE_TYPE_DELL_UTIL               0xde
-+#define PC_SLICE_TYPE_GPT              0xee
- #define PC_SLICE_TYPE_LINUX_RAID      0xfd
-diff -Nur grub-0.97/stage2/shared.h grub-0.97-patched/stage2/shared.h
---- grub-0.97/stage2/shared.h  2004-06-19 18:40:09.000000000 +0200
-+++ grub-0.97-patched/stage2/shared.h  2012-11-11 17:07:12.741730044 +0100
-@@ -36,8 +36,8 @@
- /* Maybe redirect memory requests through grub_scratch_mem. */
- #ifdef GRUB_UTIL
--extern char *grub_scratch_mem;
--# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
-+extern void *grub_scratch_mem;
-+# define RAW_ADDR(x) ((x) + (unsigned long) grub_scratch_mem)
- # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
- #else
- # define RAW_ADDR(x) (x)
-@@ -161,7 +161,9 @@
- #define LINUX_CL_OFFSET                       0x9000
- #define LINUX_CL_END_OFFSET           0x90FF
--#define LINUX_SETUP_MOVE_SIZE         0x9100
-+#define LINUX_CL_0202_PRM_OFFSET      0x9500
-+#define LINUX_CL_0202_PRM_END_OFFSET  0x9FFF
-+#define LINUX_SETUP_MOVE_SIZE         0xA000
- #define LINUX_CL_MAGIC                        0xA33F
- /*
-@@ -499,7 +501,11 @@
-   unsigned char linear_reserved_field_position;
-   unsigned long max_pixel_clock;
--  unsigned char reserved3[189];
-+  /* Reserved field to make structure to be 256 bytes long, VESA BIOS 
-+     Extension 3.0 Specification says to reserve 189 bytes here but 
-+     that doesn't make structure to be 256 bytes.  So additional one is 
-+     added here.  */
-+  unsigned char reserved3[189 + 1];
- } __attribute__ ((packed));
-@@ -807,7 +813,7 @@
- /* Low-level disk I/O */
- int get_diskinfo (int drive, struct geometry *geometry);
- int biosdisk (int subfunc, int drive, struct geometry *geometry,
--            int sector, int nsec, int segment);
-+            unsigned int sector, int nsec, int segment);
- void stop_floppy (void);
- /* Command-line interface functions. */
-@@ -871,6 +877,7 @@
- int grub_tolower (int c);
- int grub_isspace (int c);
- int grub_strncat (char *s1, const char *s2, int n);
-+void grub_memcpy(void *dest, const void *src, int len);
- void *grub_memmove (void *to, const void *from, int len);
- void *grub_memset (void *start, int c, int len);
- int grub_strncat (char *s1, const char *s2, int n);
-@@ -911,7 +918,7 @@
- int nul_terminate (char *str);
- int get_based_digit (int c, int base);
- int safe_parse_maxint (char **str_ptr, int *myint_ptr);
--int memcheck (int start, int len);
-+int memcheck (unsigned long start, unsigned long len);
- void grub_putstr (const char *str);
- #ifndef NO_DECOMPRESSION
-@@ -920,10 +927,10 @@
- int gunzip_read (char *buf, int len);
- #endif /* NO_DECOMPRESSION */
--int rawread (int drive, int sector, int byte_offset, int byte_len, char *buf);
--int devread (int sector, int byte_offset, int byte_len, char *buf);
--int rawwrite (int drive, int sector, char *buf);
--int devwrite (int sector, int sector_len, char *buf);
-+int rawread (int drive, unsigned int sector, int byte_offset, int byte_len, char *buf);
-+int devread (unsigned int sector, int byte_offset, int byte_len, char *buf);
-+int rawwrite (int drive, unsigned int sector, char *buf);
-+int devwrite (unsigned int sector, int sector_len, char *buf);
- /* Parse a device string and initialize the global parameters. */
- char *set_device (char *device);
-@@ -934,7 +941,9 @@
-                   unsigned long *partition, int *type,
-                   unsigned long *start, unsigned long *len,
-                   unsigned long *offset, int *entry,
--                  unsigned long *ext_offset, char *buf);
-+                   unsigned long *ext_offset,
-+                   unsigned long *gpt_offset, int *gpt_count,
-+                   int *gpt_size, char *buf);
- /* Sets device to the one represented by the SAVED_* parameters. */
- int make_saved_active (void);
-diff -Nur grub-0.97/stage2/size_test grub-0.97-patched/stage2/size_test
---- grub-0.97/stage2/size_test 2004-05-14 21:30:52.000000000 +0200
-+++ grub-0.97-patched/stage2/size_test 2012-11-11 17:06:52.554085177 +0100
-@@ -36,9 +36,9 @@
- }
- # The bootloader area of a FFS partition is 14 sectors.
--check ffs_stage1_5 7168
--
--check ufs2_stage1_5 7168
-+#check ffs_stage1_5 7168
-+#
-+#check ufs2_stage1_5 7168
- # Stage 1.5 can be installed in the sectors immediately after MBR in the
- # first cylinder, so the size is (63 - 1) sectors.
-diff -Nur grub-0.97/stage2/stage2.c grub-0.97-patched/stage2/stage2.c
---- grub-0.97/stage2/stage2.c  2005-03-19 18:51:57.000000000 +0100
-+++ grub-0.97-patched/stage2/stage2.c  2012-11-11 17:07:12.742730076 +0100
-@@ -233,6 +233,7 @@
- {
-   int c, time1, time2 = -1, first_entry = 0;
-   char *cur_entry = 0;
-+  struct term_entry *prev_term = NULL;
-   /*
-    *  Main loop for menu UI.
-@@ -651,7 +652,10 @@
-                 *(new_heap++) = 0;
-                 if (config_entries)
--                  run_menu (heap, NULL, new_num_entries, new_heap, 0);
-+                  {
-+                    current_entryno = first_entry + entryno;
-+                    run_menu (heap, NULL, new_num_entries, new_heap, 0);
-+                  }
-                 else
-                   {
-                     cls ();
-@@ -714,6 +718,15 @@
-   
-   cls ();
-   setcursor (1);
-+  /* if our terminal needed initialization, we should shut it down
-+   * before booting the kernel, but we want to save what it was so
-+   * we can come back if needed */
-+  prev_term = current_term;
-+  if (current_term->shutdown) 
-+    {
-+      (*current_term->shutdown)();
-+      current_term = term_table; /* assumption: console is first */
-+    }
-   
-   while (1)
-     {
-@@ -727,7 +740,8 @@
-       cur_entry = get_entry (config_entries, first_entry + entryno, 1);
-       /* Set CURRENT_ENTRYNO for the command "savedefault".  */
--      current_entryno = first_entry + entryno;
-+      if (config_entries)
-+      current_entryno = first_entry + entryno;
-       
-       if (run_script (cur_entry, heap))
-       {
-@@ -748,6 +762,13 @@
-       break;
-     }
-+  /* if we get back here, we should go back to what our term was before */
-+  current_term = prev_term;
-+  if (current_term->startup)
-+      /* if our terminal fails to initialize, fall back to console since
-+       * it should always work */
-+      if ((*current_term->startup)() == 0)
-+          current_term = term_table; /* we know that console is first */
-   show_menu = 1;
-   goto restart;
- }
-@@ -1050,6 +1071,10 @@
-         while (is_preset);
-       }
-+      /* go ahead and make sure the terminal is setup */
-+      if (current_term->startup)
-+        (*current_term->startup)();
-+
-       if (! num_entries)
-       {
-         /* If no acceptable config file, goto command-line, starting
-diff -Nur grub-0.97/stage2/stage2.c.orig grub-0.97-patched/stage2/stage2.c.orig
---- grub-0.97/stage2/stage2.c.orig     1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/stage2/stage2.c.orig     2005-03-19 18:51:57.000000000 +0100
-@@ -0,0 +1,1067 @@
-+/*
-+ *  GRUB  --  GRand Unified Bootloader
-+ *  Copyright (C) 2000,2001,2002,2004,2005  Free Software Foundation, Inc.
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include <shared.h>
-+#include <term.h>
-+
-+grub_jmp_buf restart_env;
-+
-+#if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
-+
-+# if defined(PRESET_MENU_STRING)
-+static const char *preset_menu = PRESET_MENU_STRING;
-+# elif defined(SUPPORT_DISKLESS)
-+/* Execute the command "bootp" automatically.  */
-+static const char *preset_menu = "bootp\n";
-+# endif /* SUPPORT_DISKLESS */
-+
-+static int preset_menu_offset;
-+
-+static int
-+open_preset_menu (void)
-+{
-+#ifdef GRUB_UTIL
-+  /* Unless the user explicitly requests to use the preset menu,
-+     always opening the preset menu fails in the grub shell.  */
-+  if (! use_preset_menu)
-+    return 0;
-+#endif /* GRUB_UTIL */
-+  
-+  preset_menu_offset = 0;
-+  return preset_menu != 0;
-+}
-+
-+static int
-+read_from_preset_menu (char *buf, int maxlen)
-+{
-+  int len = grub_strlen (preset_menu + preset_menu_offset);
-+
-+  if (len > maxlen)
-+    len = maxlen;
-+
-+  grub_memmove (buf, preset_menu + preset_menu_offset, len);
-+  preset_menu_offset += len;
-+
-+  return len;
-+}
-+
-+static void
-+close_preset_menu (void)
-+{
-+  /* Disable the preset menu.  */
-+  preset_menu = 0;
-+}
-+
-+#else /* ! PRESET_MENU_STRING && ! SUPPORT_DISKLESS */
-+
-+#define open_preset_menu()    0
-+#define read_from_preset_menu(buf, maxlen)    0
-+#define close_preset_menu()
-+
-+#endif /* ! PRESET_MENU_STRING && ! SUPPORT_DISKLESS */
-+
-+static char *
-+get_entry (char *list, int num, int nested)
-+{
-+  int i;
-+
-+  for (i = 0; i < num; i++)
-+    {
-+      do
-+      {
-+        while (*(list++));
-+      }
-+      while (nested && *(list++));
-+    }
-+
-+  return list;
-+}
-+
-+/* Print an entry in a line of the menu box.  */
-+static void
-+print_entry (int y, int highlight, char *entry)
-+{
-+  int x;
-+
-+  if (current_term->setcolorstate)
-+    current_term->setcolorstate (COLOR_STATE_NORMAL);
-+  
-+  if (highlight && current_term->setcolorstate)
-+    current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
-+
-+  gotoxy (2, y);
-+  grub_putchar (' ');
-+  for (x = 3; x < 75; x++)
-+    {
-+      if (*entry && x <= 72)
-+      {
-+        if (x == 72)
-+          grub_putchar (DISP_RIGHT);
-+        else
-+          grub_putchar (*entry++);
-+      }
-+      else
-+      grub_putchar (' ');
-+    }
-+  gotoxy (74, y);
-+
-+  if (current_term->setcolorstate)
-+    current_term->setcolorstate (COLOR_STATE_STANDARD);
-+}
-+
-+/* Print entries in the menu box.  */
-+static void
-+print_entries (int y, int size, int first, int entryno, char *menu_entries)
-+{
-+  int i;
-+  
-+  gotoxy (77, y + 1);
-+
-+  if (first)
-+    grub_putchar (DISP_UP);
-+  else
-+    grub_putchar (' ');
-+
-+  menu_entries = get_entry (menu_entries, first, 0);
-+
-+  for (i = 0; i < size; i++)
-+    {
-+      print_entry (y + i + 1, entryno == i, menu_entries);
-+
-+      while (*menu_entries)
-+      menu_entries++;
-+
-+      if (*(menu_entries - 1))
-+      menu_entries++;
-+    }
-+
-+  gotoxy (77, y + size);
-+
-+  if (*menu_entries)
-+    grub_putchar (DISP_DOWN);
-+  else
-+    grub_putchar (' ');
-+
-+  gotoxy (74, y + entryno + 1);
-+}
-+
-+static void
-+print_entries_raw (int size, int first, char *menu_entries)
-+{
-+  int i;
-+
-+#define LINE_LENGTH 67
-+
-+  for (i = 0; i < LINE_LENGTH; i++)
-+    grub_putchar ('-');
-+  grub_putchar ('\n');
-+
-+  for (i = first; i < size; i++)
-+    {
-+      /* grub's printf can't %02d so ... */
-+      if (i < 10)
-+      grub_putchar (' ');
-+      grub_printf ("%d: %s\n", i, get_entry (menu_entries, i, 0));
-+    }
-+
-+  for (i = 0; i < LINE_LENGTH; i++)
-+    grub_putchar ('-');
-+  grub_putchar ('\n');
-+
-+#undef LINE_LENGTH
-+}
-+
-+
-+static void
-+print_border (int y, int size)
-+{
-+  int i;
-+
-+  if (current_term->setcolorstate)
-+    current_term->setcolorstate (COLOR_STATE_NORMAL);
-+  
-+  gotoxy (1, y);
-+
-+  grub_putchar (DISP_UL);
-+  for (i = 0; i < 73; i++)
-+    grub_putchar (DISP_HORIZ);
-+  grub_putchar (DISP_UR);
-+
-+  i = 1;
-+  while (1)
-+    {
-+      gotoxy (1, y + i);
-+
-+      if (i > size)
-+      break;
-+      
-+      grub_putchar (DISP_VERT);
-+      gotoxy (75, y + i);
-+      grub_putchar (DISP_VERT);
-+
-+      i++;
-+    }
-+
-+  grub_putchar (DISP_LL);
-+  for (i = 0; i < 73; i++)
-+    grub_putchar (DISP_HORIZ);
-+  grub_putchar (DISP_LR);
-+
-+  if (current_term->setcolorstate)
-+    current_term->setcolorstate (COLOR_STATE_STANDARD);
-+}
-+
-+static void
-+run_menu (char *menu_entries, char *config_entries, int num_entries,
-+        char *heap, int entryno)
-+{
-+  int c, time1, time2 = -1, first_entry = 0;
-+  char *cur_entry = 0;
-+
-+  /*
-+   *  Main loop for menu UI.
-+   */
-+
-+restart:
-+  /* Dumb terminal always use all entries for display 
-+     invariant for TERM_DUMB: first_entry == 0  */
-+  if (! (current_term->flags & TERM_DUMB))
-+    {
-+      while (entryno > 11)
-+      {
-+        first_entry++;
-+        entryno--;
-+      }
-+    }
-+
-+  /* If the timeout was expired or wasn't set, force to show the menu
-+     interface. */
-+  if (grub_timeout < 0)
-+    show_menu = 1;
-+  
-+  /* If SHOW_MENU is false, don't display the menu until ESC is pressed.  */
-+  if (! show_menu)
-+    {
-+      /* Get current time.  */
-+      while ((time1 = getrtsecs ()) == 0xFF)
-+      ;
-+
-+      while (1)
-+      {
-+        /* Check if ESC is pressed.  */
-+        if (checkkey () != -1 && ASCII_CHAR (getkey ()) == '\e')
-+          {
-+            grub_timeout = -1;
-+            show_menu = 1;
-+            break;
-+          }
-+
-+        /* If GRUB_TIMEOUT is expired, boot the default entry.  */
-+        if (grub_timeout >=0
-+            && (time1 = getrtsecs ()) != time2
-+            && time1 != 0xFF)
-+          {
-+            if (grub_timeout <= 0)
-+              {
-+                grub_timeout = -1;
-+                goto boot_entry;
-+              }
-+            
-+            time2 = time1;
-+            grub_timeout--;
-+            
-+            /* Print a message.  */
-+            grub_printf ("\rPress `ESC' to enter the menu... %d   ",
-+                         grub_timeout);
-+          }
-+      }
-+    }
-+
-+  /* Only display the menu if the user wants to see it. */
-+  if (show_menu)
-+    {
-+      init_page ();
-+      setcursor (0);
-+
-+      if (current_term->flags & TERM_DUMB)
-+      print_entries_raw (num_entries, first_entry, menu_entries);
-+      else
-+      print_border (3, 12);
-+
-+      grub_printf ("\n\
-+      Use the %c and %c keys to select which entry is highlighted.\n",
-+                 DISP_UP, DISP_DOWN);
-+      
-+      if (! auth && password)
-+      {
-+        printf ("\
-+      Press enter to boot the selected OS or \'p\' to enter a\n\
-+      password to unlock the next set of features.");
-+      }
-+      else
-+      {
-+        if (config_entries)
-+          printf ("\
-+      Press enter to boot the selected OS, \'e\' to edit the\n\
-+      commands before booting, or \'c\' for a command-line.");
-+        else
-+          printf ("\
-+      Press \'b\' to boot, \'e\' to edit the selected command in the\n\
-+      boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
-+      after (\'O\' for before) the selected line, \'d\' to remove the\n\
-+      selected line, or escape to go back to the main menu.");
-+      }
-+
-+      if (current_term->flags & TERM_DUMB)
-+      grub_printf ("\n\nThe selected entry is %d ", entryno);
-+      else
-+      print_entries (3, 12, first_entry, entryno, menu_entries);
-+    }
-+
-+  /* XX using RT clock now, need to initialize value */
-+  while ((time1 = getrtsecs()) == 0xFF);
-+
-+  while (1)
-+    {
-+      /* Initialize to NULL just in case...  */
-+      cur_entry = NULL;
-+
-+      if (grub_timeout >= 0 && (time1 = getrtsecs()) != time2 && time1 != 0xFF)
-+      {
-+        if (grub_timeout <= 0)
-+          {
-+            grub_timeout = -1;
-+            break;
-+          }
-+
-+        /* else not booting yet! */
-+        time2 = time1;
-+
-+        if (current_term->flags & TERM_DUMB)
-+            grub_printf ("\r    Entry %d will be booted automatically in %d seconds.   ", 
-+                         entryno, grub_timeout);
-+        else
-+          {
-+            gotoxy (3, 22);
-+            grub_printf ("The highlighted entry will be booted automatically in %d seconds.    ",
-+                         grub_timeout);
-+            gotoxy (74, 4 + entryno);
-+        }
-+        
-+        grub_timeout--;
-+      }
-+
-+      /* Check for a keypress, however if TIMEOUT has been expired
-+       (GRUB_TIMEOUT == -1) relax in GETKEY even if no key has been
-+       pressed.  
-+       This avoids polling (relevant in the grub-shell and later on
-+       in grub if interrupt driven I/O is done).  */
-+      if (checkkey () >= 0 || grub_timeout < 0)
-+      {
-+        /* Key was pressed, show which entry is selected before GETKEY,
-+           since we're comming in here also on GRUB_TIMEOUT == -1 and
-+           hang in GETKEY */
-+        if (current_term->flags & TERM_DUMB)
-+          grub_printf ("\r    Highlighted entry is %d: ", entryno);
-+
-+        c = ASCII_CHAR (getkey ());
-+
-+        if (grub_timeout >= 0)
-+          {
-+            if (current_term->flags & TERM_DUMB)
-+              grub_putchar ('\r');
-+            else
-+              gotoxy (3, 22);
-+            printf ("                                                                    ");
-+            grub_timeout = -1;
-+            fallback_entryno = -1;
-+            if (! (current_term->flags & TERM_DUMB))
-+              gotoxy (74, 4 + entryno);
-+          }
-+
-+        /* We told them above (at least in SUPPORT_SERIAL) to use
-+           '^' or 'v' so accept these keys.  */
-+        if (c == 16 || c == '^')
-+          {
-+            if (current_term->flags & TERM_DUMB)
-+              {
-+                if (entryno > 0)
-+                  entryno--;
-+              }
-+            else
-+              {
-+                if (entryno > 0)
-+                  {
-+                    print_entry (4 + entryno, 0,
-+                                 get_entry (menu_entries,
-+                                            first_entry + entryno,
-+                                            0));
-+                    entryno--;
-+                    print_entry (4 + entryno, 1,
-+                                 get_entry (menu_entries,
-+                                            first_entry + entryno,
-+                                            0));
-+                  }
-+                else if (first_entry > 0)
-+                  {
-+                    first_entry--;
-+                    print_entries (3, 12, first_entry, entryno,
-+                                   menu_entries);
-+                  }
-+              }
-+          }
-+        else if ((c == 14 || c == 'v')
-+                 && first_entry + entryno + 1 < num_entries)
-+          {
-+            if (current_term->flags & TERM_DUMB)
-+              entryno++;
-+            else
-+              {
-+                if (entryno < 11)
-+                  {
-+                    print_entry (4 + entryno, 0,
-+                                 get_entry (menu_entries,
-+                                            first_entry + entryno,
-+                                            0));
-+                    entryno++;
-+                    print_entry (4 + entryno, 1,
-+                                 get_entry (menu_entries,
-+                                            first_entry + entryno,
-+                                            0));
-+                }
-+              else if (num_entries > 12 + first_entry)
-+                {
-+                  first_entry++;
-+                  print_entries (3, 12, first_entry, entryno, menu_entries);
-+                }
-+              }
-+          }
-+        else if (c == 7)
-+          {
-+            /* Page Up */
-+            first_entry -= 12;
-+            if (first_entry < 0)
-+              {
-+                entryno += first_entry;
-+                first_entry = 0;
-+                if (entryno < 0)
-+                  entryno = 0;
-+              }
-+            print_entries (3, 12, first_entry, entryno, menu_entries);
-+          }
-+        else if (c == 3)
-+          {
-+            /* Page Down */
-+            first_entry += 12;
-+            if (first_entry + entryno + 1 >= num_entries)
-+              {
-+                first_entry = num_entries - 12;
-+                if (first_entry < 0)
-+                  first_entry = 0;
-+                entryno = num_entries - first_entry - 1;
-+              }
-+            print_entries (3, 12, first_entry, entryno, menu_entries);
-+          }
-+
-+        if (config_entries)
-+          {
-+            if ((c == '\n') || (c == '\r') || (c == 6))
-+              break;
-+          }
-+        else
-+          {
-+            if ((c == 'd') || (c == 'o') || (c == 'O'))
-+              {
-+                if (! (current_term->flags & TERM_DUMB))
-+                  print_entry (4 + entryno, 0,
-+                               get_entry (menu_entries,
-+                                          first_entry + entryno,
-+                                          0));
-+
-+                /* insert after is almost exactly like insert before */
-+                if (c == 'o')
-+                  {
-+                    /* But `o' differs from `O', since it may causes
-+                       the menu screen to scroll up.  */
-+                    if (entryno < 11 || (current_term->flags & TERM_DUMB))
-+                      entryno++;
-+                    else
-+                      first_entry++;
-+                    
-+                    c = 'O';
-+                  }
-+
-+                cur_entry = get_entry (menu_entries,
-+                                       first_entry + entryno,
-+                                       0);
-+
-+                if (c == 'O')
-+                  {
-+                    grub_memmove (cur_entry + 2, cur_entry,
-+                                  ((int) heap) - ((int) cur_entry));
-+
-+                    cur_entry[0] = ' ';
-+                    cur_entry[1] = 0;
-+
-+                    heap += 2;
-+
-+                    num_entries++;
-+                  }
-+                else if (num_entries > 0)
-+                  {
-+                    char *ptr = get_entry(menu_entries,
-+                                          first_entry + entryno + 1,
-+                                          0);
-+
-+                    grub_memmove (cur_entry, ptr,
-+                                  ((int) heap) - ((int) ptr));
-+                    heap -= (((int) ptr) - ((int) cur_entry));
-+
-+                    num_entries--;
-+
-+                    if (entryno >= num_entries)
-+                      entryno--;
-+                    if (first_entry && num_entries < 12 + first_entry)
-+                      first_entry--;
-+                  }
-+
-+                if (current_term->flags & TERM_DUMB)
-+                  {
-+                    grub_printf ("\n\n");
-+                    print_entries_raw (num_entries, first_entry,
-+                                       menu_entries);
-+                    grub_printf ("\n");
-+                  }
-+                else
-+                  print_entries (3, 12, first_entry, entryno, menu_entries);
-+              }
-+
-+            cur_entry = menu_entries;
-+            if (c == 27)
-+              return;
-+            if (c == 'b')
-+              break;
-+          }
-+
-+        if (! auth && password)
-+          {
-+            if (c == 'p')
-+              {
-+                /* Do password check here! */
-+                char entered[32];
-+                char *pptr = password;
-+
-+                if (current_term->flags & TERM_DUMB)
-+                  grub_printf ("\r                                    ");
-+                else
-+                  gotoxy (1, 21);
-+
-+                /* Wipe out the previously entered password */
-+                grub_memset (entered, 0, sizeof (entered));
-+                get_cmdline (" Password: ", entered, 31, '*', 0);
-+
-+                while (! isspace (*pptr) && *pptr)
-+                  pptr++;
-+
-+                /* Make sure that PASSWORD is NUL-terminated.  */
-+                *pptr++ = 0;
-+
-+                if (! check_password (entered, password, password_type))
-+                  {
-+                    char *new_file = config_file;
-+                    while (isspace (*pptr))
-+                      pptr++;
-+
-+                    /* If *PPTR is NUL, then allow the user to use
-+                       privileged instructions, otherwise, load
-+                       another configuration file.  */
-+                    if (*pptr != 0)
-+                      {
-+                        while ((*(new_file++) = *(pptr++)) != 0)
-+                          ;
-+
-+                        /* Make sure that the user will not have
-+                           authority in the next configuration.  */
-+                        auth = 0;
-+                        return;
-+                      }
-+                    else
-+                      {
-+                        /* Now the user is superhuman.  */
-+                        auth = 1;
-+                        goto restart;
-+                      }
-+                  }
-+                else
-+                  {
-+                    grub_printf ("Failed!\n      Press any key to continue...");
-+                    getkey ();
-+                    goto restart;
-+                  }
-+              }
-+          }
-+        else
-+          {
-+            if (c == 'e')
-+              {
-+                int new_num_entries = 0, i = 0;
-+                char *new_heap;
-+
-+                if (config_entries)
-+                  {
-+                    new_heap = heap;
-+                    cur_entry = get_entry (config_entries,
-+                                           first_entry + entryno,
-+                                           1);
-+                  }
-+                else
-+                  {
-+                    /* safe area! */
-+                    new_heap = heap + NEW_HEAPSIZE + 1;
-+                    cur_entry = get_entry (menu_entries,
-+                                           first_entry + entryno,
-+                                           0);
-+                  }
-+
-+                do
-+                  {
-+                    while ((*(new_heap++) = cur_entry[i++]) != 0);
-+                    new_num_entries++;
-+                  }
-+                while (config_entries && cur_entry[i]);
-+
-+                /* this only needs to be done if config_entries is non-NULL,
-+                   but it doesn't hurt to do it always */
-+                *(new_heap++) = 0;
-+
-+                if (config_entries)
-+                  run_menu (heap, NULL, new_num_entries, new_heap, 0);
-+                else
-+                  {
-+                    cls ();
-+                    print_cmdline_message (0);
-+
-+                    new_heap = heap + NEW_HEAPSIZE + 1;
-+
-+                    saved_drive = boot_drive;
-+                    saved_partition = install_partition;
-+                    current_drive = GRUB_INVALID_DRIVE;
-+
-+                    if (! get_cmdline (PACKAGE " edit> ", new_heap,
-+                                       NEW_HEAPSIZE + 1, 0, 1))
-+                      {
-+                        int j = 0;
-+
-+                        /* get length of new command */
-+                        while (new_heap[j++])
-+                          ;
-+
-+                        if (j < 2)
-+                          {
-+                            j = 2;
-+                            new_heap[0] = ' ';
-+                            new_heap[1] = 0;
-+                          }
-+
-+                        /* align rest of commands properly */
-+                        grub_memmove (cur_entry + j, cur_entry + i,
-+                                      (int) heap - ((int) cur_entry + i));
-+
-+                        /* copy command to correct area */
-+                        grub_memmove (cur_entry, new_heap, j);
-+
-+                        heap += (j - i);
-+                      }
-+                  }
-+
-+                goto restart;
-+              }
-+            if (c == 'c')
-+              {
-+                enter_cmdline (heap, 0);
-+                goto restart;
-+              }
-+#ifdef GRUB_UTIL
-+            if (c == 'q')
-+              {
-+                /* The same as ``quit''.  */
-+                stop ();
-+              }
-+#endif
-+          }
-+      }
-+    }
-+  
-+  /* Attempt to boot an entry.  */
-+  
-+ boot_entry:
-+  
-+  cls ();
-+  setcursor (1);
-+  
-+  while (1)
-+    {
-+      if (config_entries)
-+      printf ("  Booting \'%s\'\n\n",
-+              get_entry (menu_entries, first_entry + entryno, 0));
-+      else
-+      printf ("  Booting command-list\n\n");
-+
-+      if (! cur_entry)
-+      cur_entry = get_entry (config_entries, first_entry + entryno, 1);
-+
-+      /* Set CURRENT_ENTRYNO for the command "savedefault".  */
-+      current_entryno = first_entry + entryno;
-+      
-+      if (run_script (cur_entry, heap))
-+      {
-+        if (fallback_entryno >= 0)
-+          {
-+            cur_entry = NULL;
-+            first_entry = 0;
-+            entryno = fallback_entries[fallback_entryno];
-+            fallback_entryno++;
-+            if (fallback_entryno >= MAX_FALLBACK_ENTRIES
-+                || fallback_entries[fallback_entryno] < 0)
-+              fallback_entryno = -1;
-+          }
-+        else
-+          break;
-+      }
-+      else
-+      break;
-+    }
-+
-+  show_menu = 1;
-+  goto restart;
-+}
-+
-+
-+static int
-+get_line_from_config (char *cmdline, int maxlen, int read_from_file)
-+{
-+  int pos = 0, literal = 0, comment = 0;
-+  char c;  /* since we're loading it a byte at a time! */
-+  
-+  while (1)
-+    {
-+      if (read_from_file)
-+      {
-+        if (! grub_read (&c, 1))
-+          break;
-+      }
-+      else
-+      {
-+        if (! read_from_preset_menu (&c, 1))
-+          break;
-+      }
-+
-+      /* Skip all carriage returns.  */
-+      if (c == '\r')
-+      continue;
-+
-+      /* Replace tabs with spaces.  */
-+      if (c == '\t')
-+      c = ' ';
-+
-+      /* The previous is a backslash, then...  */
-+      if (literal)
-+      {
-+        /* If it is a newline, replace it with a space and continue.  */
-+        if (c == '\n')
-+          {
-+            c = ' ';
-+            
-+            /* Go back to overwrite a backslash.  */
-+            if (pos > 0)
-+              pos--;
-+          }
-+          
-+        literal = 0;
-+      }
-+        
-+      /* translate characters first! */
-+      if (c == '\\' && ! literal)
-+      literal = 1;
-+
-+      if (comment)
-+      {
-+        if (c == '\n')
-+          comment = 0;
-+      }
-+      else if (! pos)
-+      {
-+        if (c == '#')
-+          comment = 1;
-+        else if ((c != ' ') && (c != '\n'))
-+          cmdline[pos++] = c;
-+      }
-+      else
-+      {
-+        if (c == '\n')
-+          break;
-+
-+        if (pos < maxlen)
-+          cmdline[pos++] = c;
-+      }
-+    }
-+
-+  cmdline[pos] = 0;
-+
-+  return pos;
-+}
-+
-+
-+/* This is the starting function in C.  */
-+void
-+cmain (void)
-+{
-+  int config_len, menu_len, num_entries;
-+  char *config_entries, *menu_entries;
-+  char *kill_buf = (char *) KILL_BUF;
-+
-+  auto void reset (void);
-+  void reset (void)
-+    {
-+      count_lines = -1;
-+      config_len = 0;
-+      menu_len = 0;
-+      num_entries = 0;
-+      config_entries = (char *) mbi.drives_addr + mbi.drives_length;
-+      menu_entries = (char *) MENU_BUF;
-+      init_config ();
-+    }
-+  
-+  /* Initialize the environment for restarting Stage 2.  */
-+  grub_setjmp (restart_env);
-+  
-+  /* Initialize the kill buffer.  */
-+  *kill_buf = 0;
-+
-+  /* Never return.  */
-+  for (;;)
-+    {
-+      int is_opened, is_preset;
-+
-+      reset ();
-+      
-+      /* Here load the configuration file.  */
-+      
-+#ifdef GRUB_UTIL
-+      if (use_config_file)
-+#endif /* GRUB_UTIL */
-+      {
-+        char *default_file = (char *) DEFAULT_FILE_BUF;
-+        int i;
-+        
-+        /* Get a saved default entry if possible.  */
-+        saved_entryno = 0;
-+        *default_file = 0;
-+        grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
-+        for (i = grub_strlen(default_file); i >= 0; i--)
-+          if (default_file[i] == '/')
-+            {
-+              i++;
-+              break;
-+            }
-+        default_file[i] = 0;
-+        grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
-+        if (grub_open (default_file))
-+          {
-+            char buf[10]; /* This is good enough.  */
-+            char *p = buf;
-+            int len;
-+            
-+            len = grub_read (buf, sizeof (buf));
-+            if (len > 0)
-+              {
-+                buf[sizeof (buf) - 1] = 0;
-+                safe_parse_maxint (&p, &saved_entryno);
-+              }
-+
-+            grub_close ();
-+          }
-+        errnum = ERR_NONE;
-+        
-+        do
-+          {
-+            /* STATE 0:  Before any title command.
-+               STATE 1:  In a title command.
-+               STATE >1: In a entry after a title command.  */
-+            int state = 0, prev_config_len = 0, prev_menu_len = 0;
-+            char *cmdline;
-+
-+            /* Try the preset menu first. This will succeed at most once,
-+               because close_preset_menu disables the preset menu.  */
-+            is_opened = is_preset = open_preset_menu ();
-+            if (! is_opened)
-+              {
-+                is_opened = grub_open (config_file);
-+                errnum = ERR_NONE;
-+              }
-+
-+            if (! is_opened)
-+              break;
-+
-+            /* This is necessary, because the menu must be overrided.  */
-+            reset ();
-+            
-+            cmdline = (char *) CMDLINE_BUF;
-+            while (get_line_from_config (cmdline, NEW_HEAPSIZE,
-+                                         ! is_preset))
-+              {
-+                struct builtin *builtin;
-+                
-+                /* Get the pointer to the builtin structure.  */
-+                builtin = find_command (cmdline);
-+                errnum = 0;
-+                if (! builtin)
-+                  /* Unknown command. Just skip now.  */
-+                  continue;
-+                
-+                if (builtin->flags & BUILTIN_TITLE)
-+                  {
-+                    char *ptr;
-+                    
-+                    /* the command "title" is specially treated.  */
-+                    if (state > 1)
-+                      {
-+                        /* The next title is found.  */
-+                        num_entries++;
-+                        config_entries[config_len++] = 0;
-+                        prev_menu_len = menu_len;
-+                        prev_config_len = config_len;
-+                      }
-+                    else
-+                      {
-+                        /* The first title is found.  */
-+                        menu_len = prev_menu_len;
-+                        config_len = prev_config_len;
-+                      }
-+                    
-+                    /* Reset the state.  */
-+                    state = 1;
-+                    
-+                    /* Copy title into menu area.  */
-+                    ptr = skip_to (1, cmdline);
-+                    while ((menu_entries[menu_len++] = *(ptr++)) != 0)
-+                      ;
-+                  }
-+                else if (! state)
-+                  {
-+                    /* Run a command found is possible.  */
-+                    if (builtin->flags & BUILTIN_MENU)
-+                      {
-+                        char *arg = skip_to (1, cmdline);
-+                        (builtin->func) (arg, BUILTIN_MENU);
-+                        errnum = 0;
-+                      }
-+                    else
-+                      /* Ignored.  */
-+                      continue;
-+                  }
-+                else
-+                  {
-+                    char *ptr = cmdline;
-+                    
-+                    state++;
-+                    /* Copy config file data to config area.  */
-+                    while ((config_entries[config_len++] = *ptr++) != 0)
-+                      ;
-+                  }
-+              }
-+            
-+            if (state > 1)
-+              {
-+                /* Finish the last entry.  */
-+                num_entries++;
-+                config_entries[config_len++] = 0;
-+              }
-+            else
-+              {
-+                menu_len = prev_menu_len;
-+                config_len = prev_config_len;
-+              }
-+            
-+            menu_entries[menu_len++] = 0;
-+            config_entries[config_len++] = 0;
-+            grub_memmove (config_entries + config_len, menu_entries,
-+                          menu_len);
-+            menu_entries = config_entries + config_len;
-+
-+            /* Make sure that all fallback entries are valid.  */
-+            if (fallback_entryno >= 0)
-+              {
-+                for (i = 0; i < MAX_FALLBACK_ENTRIES; i++)
-+                  {
-+                    if (fallback_entries[i] < 0)
-+                      break;
-+                    if (fallback_entries[i] >= num_entries)
-+                      {
-+                        grub_memmove (fallback_entries + i,
-+                                      fallback_entries + i + 1,
-+                                      ((MAX_FALLBACK_ENTRIES - i - 1)
-+                                       * sizeof (int)));
-+                        i--;
-+                      }
-+                  }
-+
-+                if (fallback_entries[0] < 0)
-+                  fallback_entryno = -1;
-+              }
-+            /* Check if the default entry is present. Otherwise reset
-+               it to fallback if fallback is valid, or to DEFAULT_ENTRY 
-+               if not.  */
-+            if (default_entry >= num_entries)
-+              {
-+                if (fallback_entryno >= 0)
-+                  {
-+                    default_entry = fallback_entries[0];
-+                    fallback_entryno++;
-+                    if (fallback_entryno >= MAX_FALLBACK_ENTRIES
-+                        || fallback_entries[fallback_entryno] < 0)
-+                      fallback_entryno = -1;
-+                  }
-+                else
-+                  default_entry = 0;
-+              }
-+            
-+            if (is_preset)
-+              close_preset_menu ();
-+            else
-+              grub_close ();
-+          }
-+        while (is_preset);
-+      }
-+
-+      if (! num_entries)
-+      {
-+        /* If no acceptable config file, goto command-line, starting
-+           heap from where the config entries would have been stored
-+           if there were any.  */
-+        enter_cmdline (config_entries, 1);
-+      }
-+      else
-+      {
-+        /* Run menu interface.  */
-+        run_menu (menu_entries, config_entries, num_entries,
-+                  menu_entries + menu_len, default_entry);
-+      }
-+    }
-+}
-diff -Nur grub-0.97/stage2/term.h grub-0.97-patched/stage2/term.h
---- grub-0.97/stage2/term.h    2003-07-09 13:45:53.000000000 +0200
-+++ grub-0.97-patched/stage2/term.h    2012-11-11 17:06:33.311470556 +0100
-@@ -60,6 +60,8 @@
-   const char *name;
-   /* The feature flags defined above.  */
-   unsigned long flags;
-+  /* Default for maximum number of lines if not specified */
-+  unsigned short max_lines;
-   /* Put a character.  */
-   void (*putchar) (int c);
-   /* Check if any input character is available.  */
-@@ -79,6 +81,11 @@
-   void (*setcolor) (int normal_color, int highlight_color);
-   /* Turn on/off the cursor.  */
-   int (*setcursor) (int on);
-+
-+  /* function to start a terminal */
-+  int (*startup) (void);
-+  /* function to use to shutdown a terminal */
-+  void (*shutdown) (void);
- };
- /* This lists up available terminals.  */
-@@ -124,4 +131,23 @@
- int hercules_setcursor (int on);
- #endif
-+#ifdef SUPPORT_GRAPHICS
-+extern int foreground, background, border, graphics_inited;
-+
-+void graphics_set_splash(char *splashfile);
-+int set_videomode (int mode);
-+void graphics_putchar (int c);
-+int graphics_getxy(void);
-+void graphics_gotoxy(int x, int y);
-+void graphics_cls(void);
-+void graphics_setcolorstate (color_state state);
-+void graphics_setcolor (int normal_color, int highlight_color);
-+void graphics_setcursor (int on);
-+int graphics_init(void);
-+void graphics_end(void);
-+
-+int hex(int v);
-+void graphics_set_palette(int idx, int red, int green, int blue);
-+#endif /* SUPPORT_GRAPHICS */
-+
- #endif /* ! GRUB_TERM_HEADER */
-diff -Nur grub-0.97/THANKS grub-0.97-patched/THANKS
---- grub-0.97/THANKS   2005-05-08 04:17:43.000000000 +0200
-+++ grub-0.97-patched/THANKS   2012-11-11 17:07:12.709729021 +0100
-@@ -121,3 +121,4 @@
- Yedidyah Bar-David <didi@post.tau.ac.il>
- Yury V. Umanets <umka@namesys.com>
- Yuri Zaporogets <yuriz@ukr.net>
-+Vitaly Fertman <vitaly@namesys.com>
-diff -Nur grub-0.97/util/grub-install.in grub-0.97-patched/util/grub-install.in
---- grub-0.97/util/grub-install.in     2004-07-24 20:57:31.000000000 +0200
-+++ grub-0.97-patched/util/grub-install.in     2012-11-11 17:07:12.748730268 +0100
-@@ -96,24 +96,27 @@
-     # Break the device name into the disk part and the partition part.
-     case "$host_os" in
-     linux*)
--      tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
-+      tmp_disk=`echo "$1" | sed -e 's%\([shv]d[a-z]\)[0-9]*$%\1%' \
-                                 -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
-                                 -e 's%\(fd[0-9]*\)$%\1%' \
-                                 -e 's%/part[0-9]*$%/disc%' \
--                                -e 's%\(c[0-7]d[0-9]*\).*$%\1%'`
--      tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]\([0-9]*\)$%\1%' \
-+                                -e 's%\(c[0-7]d[0-9]*\).*$%\1%' \
-+                                -e 's%\(e[0-9]\.[0-9]*\).*$%\1%'`
-+      tmp_part=`echo "$1" | sed -e 's%.*/[shv]d[a-z]\([0-9]*\)$%\1%' \
-                                 -e 's%.*d[0-9]*p%%' \
-                                 -e 's%.*/fd[0-9]*$%%' \
-                                 -e 's%.*/floppy/[0-9]*$%%' \
-                                 -e 's%.*/\(disc\|part\([0-9]*\)\)$%\2%' \
--                                -e 's%.*c[0-7]d[0-9]*p%%'`
-+                                -e 's%.*c[0-7]d[0-9]*p*%%' \
-+                                -e 's%.*e[0-9]\.[0-9]*p%%' \
-+                                -e 's%.*e[0-9]\.[0-9]*\$%%'`
-       ;;
-     gnu*)
-       tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
-       tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
-     freebsd* | kfreebsd*-gnu)
--      tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%r\1%' \
--                          | sed 's%r\{0,1\}\(da[0-9]*\).*$%r\1%'`
-+      tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \
-+                          | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'`
-       tmp_part=`echo "$1" \
-           | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
-                   | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
-@@ -131,7 +134,7 @@
-     # Get the drive name.
-     tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
--      | sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'`
-+      | sed 's%.*\(([hf]d[0-9][a-z0-9,]*)\).*%\1%'`
-     # If not found, print an error message and exit.
-     if test "x$tmp_drive" = x; then
-@@ -148,13 +151,13 @@
-       gnu*)
-           if echo $tmp_part | grep "^s" >/dev/null; then
-               tmp_pc_slice=`echo $tmp_part \
--                  | sed "s%s\([0-9]*\)[a-g]*$%\1%"`
-+                  | sed "s%s\([0-9]*\)[a-z]*$%\1%"`
-               tmp_drive=`echo "$tmp_drive" \
-                   | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
-           fi
--          if echo $tmp_part | grep "[a-g]$" >/dev/null; then
-+          if echo $tmp_part | grep "[a-z]$" >/dev/null; then
-               tmp_bsd_partition=`echo "$tmp_part" \
--                  | sed "s%[^a-g]*\([a-g]\)$%\1%"`
-+                  | sed "s%[^a-z]*\([a-z]\)$%\1%"`
-               tmp_drive=`echo "$tmp_drive" \
-                   | sed "s%)%,$tmp_bsd_partition)%"`
-           fi
-@@ -336,6 +339,10 @@
-     # Create a safe temporary file.
-     test -n "$mklog" && log_file=`$mklog`
-+    # Before all invocations of the grub shell, call sync to make sure
-+    # the raw device is in sync with any bufferring in filesystems.
-+    sync
-+ 
-     $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
- quit
- EOF
-@@ -450,6 +457,10 @@
- # Create a safe temporary file.
- test -n "$mklog" && log_file=`$mklog`
-+# Before all invocations of the grub shell, call sync to make sure
-+# the raw device is in sync with any bufferring in filesystems.
-+sync
-+
- # Now perform the installation.
- $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
- root $root_drive
-diff -Nur grub-0.97/util/grub-install.in.orig grub-0.97-patched/util/grub-install.in.orig
---- grub-0.97/util/grub-install.in.orig        1970-01-01 01:00:00.000000000 +0100
-+++ grub-0.97-patched/util/grub-install.in.orig        2004-07-24 20:57:31.000000000 +0200
-@@ -0,0 +1,477 @@
-+#! /bin/sh
-+
-+# Install GRUB on your drive.
-+#   Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
-+#
-+# This file is free software; you can redistribute it and/or modify it
-+# under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 2 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful, but
-+# WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+# General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program; if not, write to the Free Software
-+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+# Initialize some variables.
-+prefix=@prefix@
-+exec_prefix=@exec_prefix@
-+sbindir=@sbindir@
-+libdir=@libdir@
-+PACKAGE=@PACKAGE@
-+VERSION=@VERSION@
-+host_cpu=@host_cpu@
-+host_os=@host_os@
-+host_vendor=@host_vendor@
-+pkglibdir=${libdir}/${PACKAGE}/${host_cpu}-${host_vendor}
-+
-+grub_shell=${sbindir}/grub
-+grub_set_default=${sbindir}/grub-set-default
-+log_file=/tmp/grub-install.log.$$
-+img_file=/tmp/grub-install.img.$$
-+rootdir=
-+grub_prefix=/boot/grub
-+
-+install_device=
-+no_floppy=
-+force_lba=
-+recheck=no
-+debug=no
-+
-+# look for secure tempfile creation wrappers on this platform
-+if test -x /bin/tempfile; then
-+    mklog="/bin/tempfile --prefix=grub"
-+    mkimg="/bin/tempfile --prefix=grub"
-+elif test -x /bin/mktemp; then
-+    mklog="/bin/mktemp /tmp/grub-install.log.XXXXXX"
-+    mkimg="/bin/mktemp /tmp/grub-install.img.XXXXXX"
-+else
-+    mklog=""
-+    mkimg=""
-+fi
-+
-+# Usage: usage
-+# Print the usage.
-+usage () {
-+    cat <<EOF
-+Usage: grub-install [OPTION] install_device
-+Install GRUB on your drive.
-+
-+  -h, --help              print this message and exit
-+  -v, --version           print the version information and exit
-+  --root-directory=DIR    install GRUB images under the directory DIR
-+                          instead of the root directory
-+  --grub-shell=FILE       use FILE as the grub shell
-+  --no-floppy             do not probe any floppy drive
-+  --force-lba             force GRUB to use LBA mode even for a buggy
-+                          BIOS
-+  --recheck               probe a device map even if it already exists
-+
-+INSTALL_DEVICE can be a GRUB device name or a system device filename.
-+
-+grub-install copies GRUB images into the DIR/boot directory specfied by
-+--root-directory, and uses the grub shell to install grub into the boot
-+sector.
-+
-+Report bugs to <bug-grub@gnu.org>.
-+EOF
-+}
-+
-+# Usage: convert os_device
-+# Convert an OS device to the corresponding GRUB drive.
-+# This part is OS-specific.
-+convert () {
-+    # First, check if the device file exists.
-+    if test -e "$1"; then
-+      :
-+    else
-+      echo "$1: Not found or not a block device." 1>&2
-+      exit 1
-+    fi
-+
-+    # Break the device name into the disk part and the partition part.
-+    case "$host_os" in
-+    linux*)
-+      tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
-+                                -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
-+                                -e 's%\(fd[0-9]*\)$%\1%' \
-+                                -e 's%/part[0-9]*$%/disc%' \
-+                                -e 's%\(c[0-7]d[0-9]*\).*$%\1%'`
-+      tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]\([0-9]*\)$%\1%' \
-+                                -e 's%.*d[0-9]*p%%' \
-+                                -e 's%.*/fd[0-9]*$%%' \
-+                                -e 's%.*/floppy/[0-9]*$%%' \
-+                                -e 's%.*/\(disc\|part\([0-9]*\)\)$%\2%' \
-+                                -e 's%.*c[0-7]d[0-9]*p%%'`
-+      ;;
-+    gnu*)
-+      tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
-+      tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
-+    freebsd* | kfreebsd*-gnu)
-+      tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%r\1%' \
-+                          | sed 's%r\{0,1\}\(da[0-9]*\).*$%r\1%'`
-+      tmp_part=`echo "$1" \
-+          | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
-+                  | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
-+      ;;
-+    netbsd* | knetbsd*-gnu)
-+      tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([sw]d[0-9]*\).*$%r\1d%' \
-+          | sed 's%r\{0,1\}\(fd[0-9]*\).*$%r\1a%'`
-+      tmp_part=`echo "$1" \
-+          | sed "s%.*/r\{0,1\}[sw]d[0-9]\([abe-p]\)%\1%"`
-+      ;;
-+    *)
-+      echo "grub-install does not support your OS yet." 1>&2
-+      exit 1 ;;
-+    esac
-+
-+    # Get the drive name.
-+    tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
-+      | sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'`
-+
-+    # If not found, print an error message and exit.
-+    if test "x$tmp_drive" = x; then
-+      echo "$1 does not have any corresponding BIOS drive." 1>&2
-+      exit 1
-+    fi
-+
-+    if test "x$tmp_part" != x; then
-+      # If a partition is specified, we need to translate it into the
-+      # GRUB's syntax.
-+      case "$host_os" in
-+      linux*)
-+          echo "$tmp_drive" | sed "s%)$%,`expr $tmp_part - 1`)%" ;;
-+      gnu*)
-+          if echo $tmp_part | grep "^s" >/dev/null; then
-+              tmp_pc_slice=`echo $tmp_part \
-+                  | sed "s%s\([0-9]*\)[a-g]*$%\1%"`
-+              tmp_drive=`echo "$tmp_drive" \
-+                  | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
-+          fi
-+          if echo $tmp_part | grep "[a-g]$" >/dev/null; then
-+              tmp_bsd_partition=`echo "$tmp_part" \
-+                  | sed "s%[^a-g]*\([a-g]\)$%\1%"`
-+              tmp_drive=`echo "$tmp_drive" \
-+                  | sed "s%)%,$tmp_bsd_partition)%"`
-+          fi
-+          echo "$tmp_drive" ;;
-+      freebsd* | kfreebsd*-gnu)
-+          if echo $tmp_part | grep "^s" >/dev/null; then
-+              tmp_pc_slice=`echo $tmp_part \
-+                  | sed "s%s\([0-9]*\)[a-h]*$%\1%"`
-+              tmp_drive=`echo "$tmp_drive" \
-+                  | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
-+          fi
-+          if echo $tmp_part | grep "[a-h]$" >/dev/null; then
-+              tmp_bsd_partition=`echo "$tmp_part" \
-+                  | sed "s%s\{0,1\}[0-9]*\([a-h]\)$%\1%"`
-+              tmp_drive=`echo "$tmp_drive" \
-+                  | sed "s%)%,$tmp_bsd_partition)%"`
-+          fi
-+          echo "$tmp_drive" ;;
-+      netbsd* | knetbsd*-gnu)
-+          if echo $tmp_part | grep "^[abe-p]$" >/dev/null; then
-+              tmp_bsd_partition=`echo "$tmp_part" \
-+                  | sed "s%\([a-p]\)$%\1%"`
-+              tmp_drive=`echo "$tmp_drive" \
-+                  | sed "s%)%,$tmp_bsd_partition)%"`
-+          fi
-+          echo "$tmp_drive" ;;
-+      esac
-+    else
-+      # If no partition is specified, just print the drive name.
-+      echo "$tmp_drive"
-+    fi
-+}
-+
-+# Usage: resolve_symlink file
-+# Find the real file/device that file points at
-+resolve_symlink () {
-+      tmp_fname=$1
-+      # Resolve symlinks
-+      while test -L $tmp_fname; do
-+              tmp_new_fname=`ls -al $tmp_fname | sed -n 's%.*-> \(.*\)%\1%p'`
-+              if test -z "$tmp_new_fname"; then
-+                      echo "Unrecognized ls output" 2>&1
-+                      exit 1
-+              fi
-+
-+              # Convert relative symlinks
-+              case $tmp_new_fname in
-+                      /*) tmp_fname="$tmp_new_fname"
-+                      ;;
-+                      *) tmp_fname="`echo $tmp_fname | sed 's%/[^/]*$%%'`/$tmp_new_fname"
-+                      ;;
-+              esac
-+      done
-+      echo "$tmp_fname"
-+}
-+
-+# Usage: find_device file
-+# Find block device on which the file resides.
-+find_device () {
-+    # For now, this uses the program `df' to get the device name, but is
-+    # this really portable?
-+    tmp_fname=`df $1/ | sed -n 's%.*\(/dev/[^         ]*\).*%\1%p'`
-+
-+    if test -z "$tmp_fname"; then
-+      echo "Could not find device for $1" 2>&1
-+      exit 1
-+    fi
-+
-+      tmp_fname=`resolve_symlink $tmp_fname`
-+
-+    echo "$tmp_fname"
-+}
-+
-+# Check the arguments.
-+for option in "$@"; do
-+    case "$option" in
-+    -h | --help)
-+      usage
-+      exit 0 ;;
-+    -v | --version)
-+      echo "grub-install (GNU GRUB ${VERSION})"
-+      exit 0 ;;
-+    --root-directory=*)
-+      rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
-+    --grub-shell=*)
-+      grub_shell=`echo "$option" | sed 's/--grub-shell=//'` ;;
-+    --no-floppy)
-+      no_floppy="--no-floppy" ;;
-+    --force-lba)
-+      force_lba="--force-lba" ;;
-+    --recheck)
-+      recheck=yes ;;
-+    # This is an undocumented feature...
-+    --debug)
-+      debug=yes ;;
-+    -*)
-+      echo "Unrecognized option \`$option'" 1>&2
-+      usage
-+      exit 1
-+      ;;
-+    *)
-+      if test "x$install_device" != x; then
-+          echo "More than one install_devices?" 1>&2
-+          usage
-+          exit 1
-+      fi
-+      install_device="${option}" ;;
-+    esac
-+done
-+
-+if test "x$install_device" = x; then
-+    echo "install_device not specified." 1>&2
-+    usage
-+    exit 1
-+fi
-+
-+# If the debugging feature is enabled, print commands.
-+if test $debug = yes; then
-+    set -x
-+fi
-+
-+# Initialize these directories here, since ROOTDIR was initialized.
-+case "$host_os" in
-+netbsd* | openbsd*)
-+    # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub
-+    # instead of /boot/grub.
-+    grub_prefix=/grub
-+    bootdir=${rootdir}
-+    ;;
-+*)
-+    # Use /boot/grub by default.
-+    bootdir=${rootdir}/boot
-+    ;;
-+esac
-+
-+grubdir=${bootdir}/grub
-+device_map=${grubdir}/device.map
-+
-+# Check if GRUB is installed.
-+# This is necessary, because the user can specify "grub --read-only".
-+set $grub_shell dummy
-+if test -f "$1"; then
-+    :
-+else
-+    echo "$1: Not found." 1>&2
-+    exit 1
-+fi
-+
-+if test -f "$pkglibdir/stage1"; then
-+    :
-+else
-+    echo "${pkglibdir}/stage1: Not found." 1>&2
-+    exit 1
-+fi
-+
-+if test -f "$pkglibdir/stage2"; then
-+    :
-+else
-+    echo "${pkglibdir}/stage2: Not found." 1>&2
-+    exit 1
-+fi
-+
-+# Don't check for *stage1_5, because it is not fatal even if any
-+# Stage 1.5 does not exist.
-+
-+# Create the GRUB directory if it is not present.
-+test -d "$bootdir" || mkdir "$bootdir" || exit 1
-+test -d "$grubdir" || mkdir "$grubdir" || exit 1
-+
-+# If --recheck is specified, remove the device map, if present.
-+if test $recheck = yes; then
-+    rm -f $device_map
-+fi
-+
-+# Create the device map file if it is not present.
-+if test -f "$device_map"; then
-+    :
-+else
-+    # Create a safe temporary file.
-+    test -n "$mklog" && log_file=`$mklog`
-+
-+    $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
-+quit
-+EOF
-+    if grep "Error [0-9]*: " $log_file >/dev/null; then
-+      cat $log_file 1>&2
-+      exit 1
-+    fi
-+
-+    rm -f $log_file
-+fi
-+
-+# Make sure that there is no duplicated entry.
-+tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \
-+    | sort | uniq -d | sed -n 1p`
-+if test -n "$tmp"; then
-+    echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2
-+    exit 1
-+fi
-+
-+# Check for INSTALL_DEVICE.
-+case "$install_device" in
-+/dev/*)
-+    install_device=`resolve_symlink "$install_device"`
-+    install_drive=`convert "$install_device"`
-+    # I don't know why, but some shells wouldn't die if exit is
-+    # called in a function.
-+    if test "x$install_drive" = x; then
-+      exit 1
-+    fi ;;
-+\([hf]d[0-9]*\))
-+    install_drive="$install_device" ;;
-+[hf]d[0-9]*)
-+    # The GRUB format with no parenthesis.
-+    install_drive="($install_device)" ;;
-+*)
-+    echo "Format of install_device not recognized." 1>&2
-+    usage
-+    exit 1 ;;
-+esac
-+
-+# Get the root drive.
-+root_device=`find_device ${rootdir}`
-+bootdir_device=`find_device ${bootdir}`
-+
-+# Check if the boot directory is in the same device as the root directory.
-+if test "x$root_device" != "x$bootdir_device"; then
-+    # Perhaps the user has a separate boot partition.
-+    root_device=$bootdir_device
-+    grub_prefix="/grub"
-+fi
-+
-+# Convert the root device to a GRUB drive.
-+root_drive=`convert "$root_device"`
-+if test "x$root_drive" = x; then
-+    exit 1
-+fi
-+
-+# Check if the root directory exists in the same device as the grub
-+# directory.
-+grubdir_device=`find_device ${grubdir}`
-+
-+if test "x$grubdir_device" != "x$root_device"; then
-+    # For now, cannot deal with this situation.
-+    cat <<EOF 1>&2
-+You must set the root directory by the option --root-directory, because
-+$grubdir does not exist in the root device $root_device.
-+EOF
-+    exit 1
-+fi
-+
-+# Copy the GRUB images to the GRUB directory.
-+for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do
-+    rm -f $file || exit 1
-+done
-+for file in \
-+    ${pkglibdir}/stage1 ${pkglibdir}/stage2 ${pkglibdir}/*stage1_5; do
-+    cp -f $file ${grubdir} || exit 1
-+done
-+
-+# Make a default file.
-+${grub_set_default} --root-directory=${rootdir} default
-+
-+# Make sure that GRUB reads the same images as the host OS.
-+test -n "$mkimg" && img_file=`$mkimg`
-+test -n "$mklog" && log_file=`$mklog`
-+
-+for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do
-+    count=5
-+    tmp=`echo $file | sed "s|^${grubdir}|${grub_prefix}|"`
-+    while test $count -gt 0; do
-+      $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
-+dump ${root_drive}${tmp} ${img_file}
-+quit
-+EOF
-+      if grep "Error [0-9]*: " $log_file >/dev/null; then
-+          :
-+      elif cmp $file $img_file >/dev/null; then
-+          break
-+      fi
-+      sleep 1
-+      count=`expr $count - 1`    
-+    done
-+    if test $count -eq 0; then
-+      echo "The file $file not read correctly." 1>&2
-+      exit 1
-+    fi
-+done
-+
-+rm -f $img_file
-+rm -f $log_file
-+
-+# Create a safe temporary file.
-+test -n "$mklog" && log_file=`$mklog`
-+
-+# Now perform the installation.
-+$grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
-+root $root_drive
-+setup $force_lba --stage2=$grubdir/stage2 --prefix=$grub_prefix $install_drive
-+quit
-+EOF
-+
-+if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then
-+    cat $log_file 1>&2
-+    exit 1
-+fi
-+
-+rm -f $log_file
-+
-+# Prompt the user to check if the device map is correct.
-+echo "Installation finished. No error reported."
-+echo "This is the contents of the device map $device_map."
-+echo "Check if this is correct or not. If any of the lines is incorrect,"
-+echo "fix it and re-run the script \`grub-install'."
-+echo
-+
-+cat $device_map
-+
-+# Bye.
-+exit 0
-diff -Nur grub-0.97/util/mkbimage grub-0.97-patched/util/mkbimage
---- grub-0.97/util/mkbimage    2004-07-24 20:57:31.000000000 +0200
-+++ grub-0.97-patched/util/mkbimage    2012-11-11 17:07:12.744730138 +0100
-@@ -1,7 +1,7 @@
- #!/bin/sh
- # MaKe a Bootable IMAGE --- 1.44, 2.88 and El Torito no-emulation mode
- # C) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>
--# C) 2001,2002,2003 Robert Millan <robertmh@gnu.org>
-+# C) 2001,2002,2003 Robert Millan <rmh@aybabtu.com>
- # This program is free software; you can redistribute it and/or modify
-@@ -94,15 +94,13 @@
-           display Version information and exit
- Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>. 
--Copyright (c) 2001,2002 Robert Millan <zeratul2@wanadoo.es>.
- GPLed."
- version="mkbimage $version_number
--Written by Thierry Laronde and Robert Millan.
-+Written by Thierry Laronde.
- Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>.
--Copyright (c) 2001,2002,2003 Robert Millan <zeratul2@wanadoo.es>.
- This is free software under the GPL version 2 or later; see the source for 
- copying conditions.  There is NO warranty, not even for MERCHANTABILITY or 
diff --git a/src/patches/lcd4linux-scaletext-dpf.patch b/src/patches/lcd4linux-scaletext-dpf.patch
deleted file mode 100644 (file)
index c075dc7..0000000
+++ /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 (file)
index 9272c37..0000000
+++ /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 (file)
index 6053185..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
---- libcap-1.10.old/libcap/cap_sys.c   2003-08-24 19:03:35.524759616 -0700
-+++ libcap-1.10/libcap/cap_sys.c       2003-08-24 19:03:48.406801248 -0700
-@@ -10,7 +10,7 @@
- #include "libcap.h"
- #define __LIBRARY__
- #include <linux/unistd.h>
--
-+/*
- _syscall2(int, capget,
-         cap_user_header_t, header,
-         cap_user_data_t, data)
-@@ -18,7 +18,7 @@
- _syscall2(int, capset,
-         cap_user_header_t, header,
-         const cap_user_data_t, data)
--
-+*/
- /*
-  * $Log: libcap-1.10-syscall.patch,v $
-  * Revision 1.1  2004/01/14 13:11:39  riddles
-  * Build shared libcap
-  *
-  * Revision 1.2  2003/08/29 06:28:38  cretin
-  * Only add -fPIC for libcap.so objects
-  *
-  * Revision 1.1  2003/08/27 06:10:53  cretin
-  * Added -fPIC for prelink to work, and fixed compile error
-  *
-  * Revision 1.1.1.1  1999/04/17 22:16:31  morgan
---- libcap-1.10.old/Make.Rules Mon May 21 16:22:08 2001
-+++ libcap-1.10/Make.Rules     Mon May 21 16:22:32 2001
-@@ -44,10 +44,10 @@
- CC=gcc
- COPTFLAGS=-O2
- DEBUG=-g #-DDEBUG
--WARNINGS=-ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
-+WARNINGS=-D_POSIX_SOURCE -Wall -Wwrite-strings \
-         -Wpointer-arith -Wcast-qual -Wcast-align \
-         -Wtraditional -Wstrict-prototypes -Wmissing-prototypes \
--        -Wnested-externs -Winline -Wshadow -pedantic
-+        -Wnested-externs -Winline -Wshadow
- LD=ld
- LDFLAGS=-s #-g
diff --git a/src/patches/libnl-1.1-ULONG_MAX.patch b/src/patches/libnl-1.1-ULONG_MAX.patch
deleted file mode 100644 (file)
index ca3dd40..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
---- libnl-1.1/include/netlink-local.h.orig     2008-06-08 19:09:20.000000000 +0200
-+++ libnl-1.1/include/netlink-local.h  2008-06-08 19:09:33.000000000 +0200
-@@ -26,6 +26,7 @@
- #include <sys/socket.h>
- #include <inttypes.h>
- #include <assert.h>
-+#include <limits.h>
- #include <arpa/inet.h>
- #include <netdb.h>
-
diff --git a/src/patches/libsigc++-gcc43.patch b/src/patches/libsigc++-gcc43.patch
deleted file mode 100644 (file)
index 528f21e..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-diff -urN libsigc++-2.0-2.0.17.old/sigc++/signal.h libsigc++-2.0-2.0.17/sigc++/signal.h
---- libsigc++-2.0-2.0.17.old/sigc++/signal.h   2005-12-20 08:35:21.000000000 +0000
-+++ libsigc++-2.0-2.0.17/sigc++/signal.h       2008-02-22 00:22:44.000000000 +0000
-@@ -1661,7 +1661,7 @@
-   typedef internal::signal_emit0<T_return, T_accumulator> emitter_type;
-   typedef typename emitter_type::result_type         result_type;
-   typedef slot<T_return>    slot_type;
--  typedef slot_list<slot_type>                       slot_list_type;
-+  typedef sigc::slot_list<slot_type>                       slot_list_type;
-   typedef typename slot_list_type::iterator               iterator;
-   typedef typename slot_list_type::const_iterator         const_iterator;
-   typedef typename slot_list_type::reverse_iterator       reverse_iterator;
-@@ -1770,7 +1770,7 @@
-   typedef internal::signal_emit1<T_return, T_arg1, T_accumulator> emitter_type;
-   typedef typename emitter_type::result_type         result_type;
-   typedef slot<T_return, T_arg1>    slot_type;
--  typedef slot_list<slot_type>                       slot_list_type;
-+  typedef sigc::slot_list<slot_type>                       slot_list_type;
-   typedef typename slot_list_type::iterator               iterator;
-   typedef typename slot_list_type::const_iterator         const_iterator;
-   typedef typename slot_list_type::reverse_iterator       reverse_iterator;
-@@ -1881,7 +1881,7 @@
-   typedef internal::signal_emit2<T_return, T_arg1,T_arg2, T_accumulator> emitter_type;
-   typedef typename emitter_type::result_type         result_type;
-   typedef slot<T_return, T_arg1,T_arg2>    slot_type;
--  typedef slot_list<slot_type>                       slot_list_type;
-+  typedef sigc::slot_list<slot_type>                       slot_list_type;
-   typedef typename slot_list_type::iterator               iterator;
-   typedef typename slot_list_type::const_iterator         const_iterator;
-   typedef typename slot_list_type::reverse_iterator       reverse_iterator;
-@@ -1994,7 +1994,7 @@
-   typedef internal::signal_emit3<T_return, T_arg1,T_arg2,T_arg3, T_accumulator> emitter_type;
-   typedef typename emitter_type::result_type         result_type;
-   typedef slot<T_return, T_arg1,T_arg2,T_arg3>    slot_type;
--  typedef slot_list<slot_type>                       slot_list_type;
-+  typedef sigc::slot_list<slot_type>                       slot_list_type;
-   typedef typename slot_list_type::iterator               iterator;
-   typedef typename slot_list_type::const_iterator         const_iterator;
-   typedef typename slot_list_type::reverse_iterator       reverse_iterator;
-@@ -2109,7 +2109,7 @@
-   typedef internal::signal_emit4<T_return, T_arg1,T_arg2,T_arg3,T_arg4, T_accumulator> emitter_type;
-   typedef typename emitter_type::result_type         result_type;
-   typedef slot<T_return, T_arg1,T_arg2,T_arg3,T_arg4>    slot_type;
--  typedef slot_list<slot_type>                       slot_list_type;
-+  typedef sigc::slot_list<slot_type>                       slot_list_type;
-   typedef typename slot_list_type::iterator               iterator;
-   typedef typename slot_list_type::const_iterator         const_iterator;
-   typedef typename slot_list_type::reverse_iterator       reverse_iterator;
-@@ -2226,7 +2226,7 @@
-   typedef internal::signal_emit5<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5, T_accumulator> emitter_type;
-   typedef typename emitter_type::result_type         result_type;
-   typedef slot<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5>    slot_type;
--  typedef slot_list<slot_type>                       slot_list_type;
-+  typedef sigc::slot_list<slot_type>                       slot_list_type;
-   typedef typename slot_list_type::iterator               iterator;
-   typedef typename slot_list_type::const_iterator         const_iterator;
-   typedef typename slot_list_type::reverse_iterator       reverse_iterator;
-@@ -2345,7 +2345,7 @@
-   typedef internal::signal_emit6<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6, T_accumulator> emitter_type;
-   typedef typename emitter_type::result_type         result_type;
-   typedef slot<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6>    slot_type;
--  typedef slot_list<slot_type>                       slot_list_type;
-+  typedef sigc::slot_list<slot_type>                       slot_list_type;
-   typedef typename slot_list_type::iterator               iterator;
-   typedef typename slot_list_type::const_iterator         const_iterator;
-   typedef typename slot_list_type::reverse_iterator       reverse_iterator;
-@@ -2466,7 +2466,7 @@
-   typedef internal::signal_emit7<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6,T_arg7, T_accumulator> emitter_type;
-   typedef typename emitter_type::result_type         result_type;
-   typedef slot<T_return, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6,T_arg7>    slot_type;
--  typedef slot_list<slot_type>                       slot_list_type;
-+  typedef sigc::slot_list<slot_type>                       slot_list_type;
-   typedef typename slot_list_type::iterator               iterator;
-   typedef typename slot_list_type::const_iterator         const_iterator;
-   typedef typename slot_list_type::reverse_iterator       reverse_iterator;
-diff -urN libsigc++-2.0-2.0.17.old/tests/test_copy_invalid_slot.cc libsigc++-2.0-2.0.17/tests/test_copy_invalid_slot.cc
---- libsigc++-2.0-2.0.17.old/tests/test_copy_invalid_slot.cc   2005-05-01 02:00:47.000000000 +0000
-+++ libsigc++-2.0-2.0.17/tests/test_copy_invalid_slot.cc       2008-02-22 00:24:08.000000000 +0000
-@@ -1,4 +1,6 @@
- #include <iostream>
-+#include <cstdlib>
-+#include <cstring>
- #include <sigc++/sigc++.h>
- void Foo(sigc::trackable &t) {}
old mode 100755 (executable)
new mode 100644 (file)
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 (file)
index 795d0a3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-Submitted By: Ken Moffat <ken@kenmoffat.uklinux.net>
-Date: 2005-08-08
-Initial Package Version: 0.98.39
-Upstream Status: From upstream cvs
-Origin: Extracted by Ken Moffat
-Description:  This is Jindrich Novy's patch to fix another buffer overrun
-in nasm, CAN-2005-1194 (users who can be persuaded to assemble and run a
-malicious source file can have arbitrary code executed via a buffer
-overflow).
-
---- nasm-0.98.39/output/outieee.c.orig 2005-01-15 22:16:08.000000000 +0000
-+++ nasm-0.98.39/output/outieee.c      2005-08-08 22:12:46.000000000 +0100
-@@ -1120,7 +1120,7 @@
-     va_list ap;
-     va_start(ap, format);
--    vsprintf(buffer, format, ap);
-+    vsnprintf(buffer, sizeof(buffer), format, ap);
-     l = strlen(buffer);
-     for (i = 0; i < l; i++)
-         if ((buffer[i] & 0xff) > 31)
diff --git a/src/patches/net-tools-1.60-kernel_headers-2.patch b/src/patches/net-tools-1.60-kernel_headers-2.patch
deleted file mode 100644 (file)
index c881537..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
-Date: 2004-06-24
-Initial Package Version: 2.6
-Origin: Gentoo and Self
-Upstream Status: N/A
-Description: Fixes Compile Issues with the 2.6 Kernel
-
-diff -Naur net-tools-1.60.orig/hostname.c net-tools-1.60/hostname.c
---- net-tools-1.60.orig/hostname.c     2001-04-08 17:04:23.000000000 +0000
-+++ net-tools-1.60/hostname.c  2004-06-24 06:17:32.517305695 +0000
-@@ -42,10 +42,16 @@
- #include "config.h"
- #include "version.h"
- #include "../intl.h"
-+#include <linux/version.h>
- #if HAVE_AFDECnet
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
- #include <netdnet/dn.h>
- #endif
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
-+#include <linux/dn.h>
-+#endif
-+#endif
- char *Release = RELEASE, *Version = "hostname 1.100 (2001-04-14)";
-diff -Naur net-tools-1.60.orig/lib/x25_sr.c net-tools-1.60/lib/x25_sr.c
---- net-tools-1.60.orig/lib/x25_sr.c   2000-05-20 13:38:10.000000000 +0000
-+++ net-tools-1.60/lib/x25_sr.c        2004-06-24 06:15:45.163773724 +0000
-@@ -22,6 +22,7 @@
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <linux/x25.h>
-+#include <linux/version.h>
- #include <ctype.h>
- #include <errno.h>
- #include <netdb.h>
-@@ -77,7 +78,11 @@
-   rt.sigdigits=sigdigits;
-   /* x25_route_struct.address isn't type struct sockaddr_x25, Why? */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
-   memcpy(&rt.address, &sx25.sx25_addr, sizeof(x25_address));
-+#else
-+  memcpy(&rt.address, &sx25.sx25_addr, sizeof(struct x25_address));
-+#endif
-   while (*args) {
-       if (!strcmp(*args,"device") || !strcmp(*args,"dev")) {
diff --git a/src/patches/netfilter_layer7_2.22_kernel3.0.patch b/src/patches/netfilter_layer7_2.22_kernel3.0.patch
deleted file mode 100644 (file)
index 82d8509..0000000
+++ /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; &regdummy = don't. */
-+long regsize;         /* Code size. */
-+};
-+
-+/*
-+ * Forward declarations for regcomp()'s friends.
-+ */
-+#ifndef STATIC
-+#define       STATIC  static
-+#endif
-+STATIC char *reg(struct match_globals *g, int paren,int *flagp);
-+STATIC char *regbranch(struct match_globals *g, int *flagp);
-+STATIC char *regpiece(struct match_globals *g, int *flagp);
-+STATIC char *regatom(struct match_globals *g, int *flagp);
-+STATIC char *regnode(struct match_globals *g, char op);
-+STATIC char *regnext(struct match_globals *g, char *p);
-+STATIC void regc(struct match_globals *g, char b);
-+STATIC void reginsert(struct match_globals *g, char op, char *opnd);
-+STATIC void regtail(struct match_globals *g, char *p, char *val);
-+STATIC void regoptail(struct match_globals *g, char *p, char *val);
-+
-+
-+__kernel_size_t my_strcspn(const char *s1,const char *s2)
-+{
-+        char *scan1;
-+        char *scan2;
-+        int count;
-+
-+        count = 0;
-+        for (scan1 = (char *)s1; *scan1 != '\0'; scan1++) {
-+                for (scan2 = (char *)s2; *scan2 != '\0';)       /* ++ moved down. */
-+                        if (*scan1 == *scan2++)
-+                                return(count);
-+                count++;
-+        }
-+        return(count);
-+}
-+
-+/*
-+ - regcomp - compile a regular expression into internal code
-+ *
-+ * We can't allocate space until we know how big the compiled form will be,
-+ * but we can't compile it (and thus know how big it is) until we've got a
-+ * place to put the code.  So we cheat:  we compile it twice, once with code
-+ * generation turned off and size counting turned on, and once "for real".
-+ * This also means that we don't allocate space until we are sure that the
-+ * thing really will compile successfully, and we never have to move the
-+ * code and thus invalidate pointers into it.  (Note that it has to be in
-+ * one piece because free() must be able to free it all.)
-+ *
-+ * Beware that the optimization-preparation code in here knows about some
-+ * of the structure of the compiled regexp.
-+ */
-+regexp *
-+regcomp(char *exp,int *patternsize)
-+{
-+      register regexp *r;
-+      register char *scan;
-+      register char *longest;
-+      register int len;
-+      int flags;
-+      struct match_globals g;
-+      
-+      /* commented out by ethan
-+         extern char *malloc();
-+      */
-+
-+      if (exp == NULL)
-+              FAIL("NULL argument");
-+
-+      /* First pass: determine size, legality. */
-+      g.regparse = exp;
-+      g.regnpar = 1;
-+      g.regsize = 0L;
-+      g.regcode = &g.regdummy;
-+      regc(&g, MAGIC);
-+      if (reg(&g, 0, &flags) == NULL)
-+              return(NULL);
-+
-+      /* Small enough for pointer-storage convention? */
-+      if (g.regsize >= 32767L)                /* Probably could be 65535L. */
-+              FAIL("regexp too big");
-+
-+      /* Allocate space. */
-+      *patternsize=sizeof(regexp) + (unsigned)g.regsize;
-+      r = (regexp *)malloc(sizeof(regexp) + (unsigned)g.regsize);
-+      if (r == NULL)
-+              FAIL("out of space");
-+
-+      /* Second pass: emit code. */
-+      g.regparse = exp;
-+      g.regnpar = 1;
-+      g.regcode = r->program;
-+      regc(&g, MAGIC);
-+      if (reg(&g, 0, &flags) == NULL)
-+              return(NULL);
-+
-+      /* Dig out information for optimizations. */
-+      r->regstart = '\0';     /* Worst-case defaults. */
-+      r->reganch = 0;
-+      r->regmust = NULL;
-+      r->regmlen = 0;
-+      scan = r->program+1;                    /* First BRANCH. */
-+      if (OP(regnext(&g, scan)) == END) {             /* Only one top-level choice. */
-+              scan = OPERAND(scan);
-+
-+              /* Starting-point info. */
-+              if (OP(scan) == EXACTLY)
-+                      r->regstart = *OPERAND(scan);
-+              else if (OP(scan) == BOL)
-+                      r->reganch++;
-+
-+              /*
-+               * If there's something expensive in the r.e., find the
-+               * longest literal string that must appear and make it the
-+               * regmust.  Resolve ties in favor of later strings, since
-+               * the regstart check works with the beginning of the r.e.
-+               * and avoiding duplication strengthens checking.  Not a
-+               * strong reason, but sufficient in the absence of others.
-+               */
-+              if (flags&SPSTART) {
-+                      longest = NULL;
-+                      len = 0;
-+                      for (; scan != NULL; scan = regnext(&g, scan))
-+                              if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
-+                                      longest = OPERAND(scan);
-+                                      len = strlen(OPERAND(scan));
-+                              }
-+                      r->regmust = longest;
-+                      r->regmlen = len;
-+              }
-+      }
-+
-+      return(r);
-+}
-+
-+/*
-+ - reg - regular expression, i.e. main body or parenthesized thing
-+ *
-+ * Caller must absorb opening parenthesis.
-+ *
-+ * Combining parenthesis handling with the base level of regular expression
-+ * is a trifle forced, but the need to tie the tails of the branches to what
-+ * follows makes it hard to avoid.
-+ */
-+static char *
-+reg(struct match_globals *g, int paren, int *flagp /* Parenthesized? */ )
-+{
-+      register char *ret;
-+      register char *br;
-+      register char *ender;
-+      register int parno = 0; /* 0 makes gcc happy */
-+      int flags;
-+
-+      *flagp = HASWIDTH;      /* Tentatively. */
-+
-+      /* Make an OPEN node, if parenthesized. */
-+      if (paren) {
-+              if (g->regnpar >= NSUBEXP)
-+                      FAIL("too many ()");
-+              parno = g->regnpar;
-+              g->regnpar++;
-+              ret = regnode(g, OPEN+parno);
-+      } else
-+              ret = NULL;
-+
-+      /* Pick up the branches, linking them together. */
-+      br = regbranch(g, &flags);
-+      if (br == NULL)
-+              return(NULL);
-+      if (ret != NULL)
-+              regtail(g, ret, br);    /* OPEN -> first. */
-+      else
-+              ret = br;
-+      if (!(flags&HASWIDTH))
-+              *flagp &= ~HASWIDTH;
-+      *flagp |= flags&SPSTART;
-+      while (*g->regparse == '|') {
-+              g->regparse++;
-+              br = regbranch(g, &flags);
-+              if (br == NULL)
-+                      return(NULL);
-+              regtail(g, ret, br);    /* BRANCH -> BRANCH. */
-+              if (!(flags&HASWIDTH))
-+                      *flagp &= ~HASWIDTH;
-+              *flagp |= flags&SPSTART;
-+      }
-+
-+      /* Make a closing node, and hook it on the end. */
-+      ender = regnode(g, (paren) ? CLOSE+parno : END);        
-+      regtail(g, ret, ender);
-+
-+      /* Hook the tails of the branches to the closing node. */
-+      for (br = ret; br != NULL; br = regnext(g, br))
-+              regoptail(g, br, ender);
-+
-+      /* Check for proper termination. */
-+      if (paren && *g->regparse++ != ')') {
-+              FAIL("unmatched ()");
-+      } else if (!paren && *g->regparse != '\0') {
-+              if (*g->regparse == ')') {
-+                      FAIL("unmatched ()");
-+              } else
-+                      FAIL("junk on end");    /* "Can't happen". */
-+              /* NOTREACHED */
-+      }
-+
-+      return(ret);
-+}
-+
-+/*
-+ - regbranch - one alternative of an | operator
-+ *
-+ * Implements the concatenation operator.
-+ */
-+static char *
-+regbranch(struct match_globals *g, int *flagp)
-+{
-+      register char *ret;
-+      register char *chain;
-+      register char *latest;
-+      int flags;
-+
-+      *flagp = WORST;         /* Tentatively. */
-+
-+      ret = regnode(g, BRANCH);
-+      chain = NULL;
-+      while (*g->regparse != '\0' && *g->regparse != '|' && *g->regparse != ')') {
-+              latest = regpiece(g, &flags);
-+              if (latest == NULL)
-+                      return(NULL);
-+              *flagp |= flags&HASWIDTH;
-+              if (chain == NULL)      /* First piece. */
-+                      *flagp |= flags&SPSTART;
-+              else
-+                      regtail(g, chain, latest);
-+              chain = latest;
-+      }
-+      if (chain == NULL)      /* Loop ran zero times. */
-+              (void) regnode(g, NOTHING);
-+
-+      return(ret);
-+}
-+
-+/*
-+ - regpiece - something followed by possible [*+?]
-+ *
-+ * Note that the branching code sequences used for ? and the general cases
-+ * of * and + are somewhat optimized:  they use the same NOTHING node as
-+ * both the endmarker for their branch list and the body of the last branch.
-+ * It might seem that this node could be dispensed with entirely, but the
-+ * endmarker role is not redundant.
-+ */
-+static char *
-+regpiece(struct match_globals *g, int *flagp)
-+{
-+      register char *ret;
-+      register char op;
-+      register char *next;
-+      int flags;
-+
-+      ret = regatom(g, &flags);
-+      if (ret == NULL)
-+              return(NULL);
-+
-+      op = *g->regparse;
-+      if (!ISMULT(op)) {
-+              *flagp = flags;
-+              return(ret);
-+      }
-+
-+      if (!(flags&HASWIDTH) && op != '?')
-+              FAIL("*+ operand could be empty");
-+      *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
-+
-+      if (op == '*' && (flags&SIMPLE))
-+              reginsert(g, STAR, ret);
-+      else if (op == '*') {
-+              /* Emit x* as (x&|), where & means "self". */
-+              reginsert(g, BRANCH, ret);                      /* Either x */
-+              regoptail(g, ret, regnode(g, BACK));            /* and loop */
-+              regoptail(g, ret, ret);                 /* back */
-+              regtail(g, ret, regnode(g, BRANCH));            /* or */
-+              regtail(g, ret, regnode(g, NOTHING));           /* null. */
-+      } else if (op == '+' && (flags&SIMPLE))
-+              reginsert(g, PLUS, ret);
-+      else if (op == '+') {
-+              /* Emit x+ as x(&|), where & means "self". */
-+              next = regnode(g, BRANCH);                      /* Either */
-+              regtail(g, ret, next);
-+              regtail(g, regnode(g, BACK), ret);              /* loop back */
-+              regtail(g, next, regnode(g, BRANCH));           /* or */
-+              regtail(g, ret, regnode(g, NOTHING));           /* null. */
-+      } else if (op == '?') {
-+              /* Emit x? as (x|) */
-+              reginsert(g, BRANCH, ret);                      /* Either x */
-+              regtail(g, ret, regnode(g, BRANCH));            /* or */
-+              next = regnode(g, NOTHING);             /* null. */
-+              regtail(g, ret, next);
-+              regoptail(g, ret, next);
-+      }
-+      g->regparse++;
-+      if (ISMULT(*g->regparse))
-+              FAIL("nested *?+");
-+
-+      return(ret);
-+}
-+
-+/*
-+ - regatom - the lowest level
-+ *
-+ * Optimization:  gobbles an entire sequence of ordinary characters so that
-+ * it can turn them into a single node, which is smaller to store and
-+ * faster to run.  Backslashed characters are exceptions, each becoming a
-+ * separate node; the code is simpler that way and it's not worth fixing.
-+ */
-+static char *
-+regatom(struct match_globals *g, int *flagp)
-+{
-+      register char *ret;
-+      int flags;
-+
-+      *flagp = WORST;         /* Tentatively. */
-+
-+      switch (*g->regparse++) {
-+      case '^':
-+              ret = regnode(g, BOL);
-+              break;
-+      case '$':
-+              ret = regnode(g, EOL);
-+              break;
-+      case '.':
-+              ret = regnode(g, ANY);
-+              *flagp |= HASWIDTH|SIMPLE;
-+              break;
-+      case '[': {
-+                      register int class;
-+                      register int classend;
-+
-+                      if (*g->regparse == '^') {      /* Complement of range. */
-+                              ret = regnode(g, ANYBUT);
-+                              g->regparse++;
-+                      } else
-+                              ret = regnode(g, ANYOF);
-+                      if (*g->regparse == ']' || *g->regparse == '-')
-+                              regc(g, *g->regparse++);
-+                      while (*g->regparse != '\0' && *g->regparse != ']') {
-+                              if (*g->regparse == '-') {
-+                                      g->regparse++;
-+                                      if (*g->regparse == ']' || *g->regparse == '\0')
-+                                              regc(g, '-');
-+                                      else {
-+                                              class = UCHARAT(g->regparse-2)+1;
-+                                              classend = UCHARAT(g->regparse);
-+                                              if (class > classend+1)
-+                                                      FAIL("invalid [] range");
-+                                              for (; class <= classend; class++)
-+                                                      regc(g, class);
-+                                              g->regparse++;
-+                                      }
-+                              } else
-+                                      regc(g, *g->regparse++);
-+                      }
-+                      regc(g, '\0');
-+                      if (*g->regparse != ']')
-+                              FAIL("unmatched []");
-+                      g->regparse++;
-+                      *flagp |= HASWIDTH|SIMPLE;
-+              }
-+              break;
-+      case '(':
-+              ret = reg(g, 1, &flags);
-+              if (ret == NULL)
-+                      return(NULL);
-+              *flagp |= flags&(HASWIDTH|SPSTART);
-+              break;
-+      case '\0':
-+      case '|':
-+      case ')':
-+              FAIL("internal urp");   /* Supposed to be caught earlier. */
-+              break;
-+      case '?':
-+      case '+':
-+      case '*':
-+              FAIL("?+* follows nothing");
-+              break;
-+      case '\\':
-+              if (*g->regparse == '\0')
-+                      FAIL("trailing \\");
-+              ret = regnode(g, EXACTLY);
-+              regc(g, *g->regparse++);
-+              regc(g, '\0');
-+              *flagp |= HASWIDTH|SIMPLE;
-+              break;
-+      default: {
-+                      register int len;
-+                      register char ender;
-+
-+                      g->regparse--;
-+                      len = my_strcspn((const char *)g->regparse, (const char *)META);
-+                      if (len <= 0)
-+                              FAIL("internal disaster");
-+                      ender = *(g->regparse+len);
-+                      if (len > 1 && ISMULT(ender))
-+                              len--;          /* Back off clear of ?+* operand. */
-+                      *flagp |= HASWIDTH;
-+                      if (len == 1)
-+                              *flagp |= SIMPLE;
-+                      ret = regnode(g, EXACTLY);
-+                      while (len > 0) {
-+                              regc(g, *g->regparse++);
-+                              len--;
-+                      }
-+                      regc(g, '\0');
-+              }
-+              break;
-+      }
-+
-+      return(ret);
-+}
-+
-+/*
-+ - regnode - emit a node
-+ */
-+static char *                 /* Location. */
-+regnode(struct match_globals *g, char op)
-+{
-+      register char *ret;
-+      register char *ptr;
-+
-+      ret = g->regcode;
-+      if (ret == &g->regdummy) {
-+              g->regsize += 3;
-+              return(ret);
-+      }
-+
-+      ptr = ret;
-+      *ptr++ = op;
-+      *ptr++ = '\0';          /* Null "next" pointer. */
-+      *ptr++ = '\0';
-+      g->regcode = ptr;
-+
-+      return(ret);
-+}
-+
-+/*
-+ - regc - emit (if appropriate) a byte of code
-+ */
-+static void
-+regc(struct match_globals *g, char b)
-+{
-+      if (g->regcode != &g->regdummy)
-+              *g->regcode++ = b;
-+      else
-+              g->regsize++;
-+}
-+
-+/*
-+ - reginsert - insert an operator in front of already-emitted operand
-+ *
-+ * Means relocating the operand.
-+ */
-+static void
-+reginsert(struct match_globals *g, char op, char* opnd)
-+{
-+      register char *src;
-+      register char *dst;
-+      register char *place;
-+
-+      if (g->regcode == &g->regdummy) {
-+              g->regsize += 3;
-+              return;
-+      }
-+
-+      src = g->regcode;
-+      g->regcode += 3;
-+      dst = g->regcode;
-+      while (src > opnd)
-+              *--dst = *--src;
-+
-+      place = opnd;           /* Op node, where operand used to be. */
-+      *place++ = op;
-+      *place++ = '\0';
-+      *place++ = '\0';
-+}
-+
-+/*
-+ - regtail - set the next-pointer at the end of a node chain
-+ */
-+static void
-+regtail(struct match_globals *g, char *p, char *val)
-+{
-+      register char *scan;
-+      register char *temp;
-+      register int offset;
-+
-+      if (p == &g->regdummy)
-+              return;
-+
-+      /* Find last node. */
-+      scan = p;
-+      for (;;) {
-+              temp = regnext(g, scan);
-+              if (temp == NULL)
-+                      break;
-+              scan = temp;
-+      }
-+
-+      if (OP(scan) == BACK)
-+              offset = scan - val;
-+      else
-+              offset = val - scan;
-+      *(scan+1) = (offset>>8)&0377;
-+      *(scan+2) = offset&0377;
-+}
-+
-+/*
-+ - regoptail - regtail on operand of first argument; nop if operandless
-+ */
-+static void
-+regoptail(struct match_globals *g, char *p, char *val)
-+{
-+      /* "Operandless" and "op != BRANCH" are synonymous in practice. */
-+      if (p == NULL || p == &g->regdummy || OP(p) != BRANCH)
-+              return;
-+      regtail(g, OPERAND(p), val);
-+}
-+
-+/*
-+ * regexec and friends
-+ */
-+
-+
-+/*
-+ * Forwards.
-+ */
-+STATIC int regtry(struct match_globals *g, regexp *prog, char *string);
-+STATIC int regmatch(struct match_globals *g, char *prog);
-+STATIC int regrepeat(struct match_globals *g, char *p);
-+
-+#ifdef DEBUG
-+int regnarrate = 0;
-+void regdump();
-+STATIC char *regprop(char *op);
-+#endif
-+
-+/*
-+ - regexec - match a regexp against a string
-+ */
-+int
-+regexec(regexp *prog, char *string)
-+{
-+      register char *s;
-+      struct match_globals g;
-+
-+      /* Be paranoid... */
-+      if (prog == NULL || string == NULL) {
-+              printk("<3>Regexp: NULL parameter\n");
-+              return(0);
-+      }
-+
-+      /* Check validity of program. */
-+      if (UCHARAT(prog->program) != MAGIC) {
-+              printk("<3>Regexp: corrupted program\n");
-+              return(0);
-+      }
-+
-+      /* If there is a "must appear" string, look for it. */
-+      if (prog->regmust != NULL) {
-+              s = string;
-+              while ((s = strchr(s, prog->regmust[0])) != NULL) {
-+                      if (strncmp(s, prog->regmust, prog->regmlen) == 0)
-+                              break;  /* Found it. */
-+                      s++;
-+              }
-+              if (s == NULL)  /* Not present. */
-+                      return(0);
-+      }
-+
-+      /* Mark beginning of line for ^ . */
-+      g.regbol = string;
-+
-+      /* Simplest case:  anchored match need be tried only once. */
-+      if (prog->reganch)
-+              return(regtry(&g, prog, string));
-+
-+      /* Messy cases:  unanchored match. */
-+      s = string;
-+      if (prog->regstart != '\0')
-+              /* We know what char it must start with. */
-+              while ((s = strchr(s, prog->regstart)) != NULL) {
-+                      if (regtry(&g, prog, s))
-+                              return(1);
-+                      s++;
-+              }
-+      else
-+              /* We don't -- general case. */
-+              do {
-+                      if (regtry(&g, prog, s))
-+                              return(1);
-+              } while (*s++ != '\0');
-+
-+      /* Failure. */
-+      return(0);
-+}
-+
-+/*
-+ - regtry - try match at specific point
-+ */
-+static int                    /* 0 failure, 1 success */
-+regtry(struct match_globals *g, regexp *prog, char *string)
-+{
-+      register int i;
-+      register char **sp;
-+      register char **ep;
-+
-+      g->reginput = string;
-+      g->regstartp = prog->startp;
-+      g->regendp = prog->endp;
-+
-+      sp = prog->startp;
-+      ep = prog->endp;
-+      for (i = NSUBEXP; i > 0; i--) {
-+              *sp++ = NULL;
-+              *ep++ = NULL;
-+      }
-+      if (regmatch(g, prog->program + 1)) {
-+              prog->startp[0] = string;
-+              prog->endp[0] = g->reginput;
-+              return(1);
-+      } else
-+              return(0);
-+}
-+
-+/*
-+ - regmatch - main matching routine
-+ *
-+ * Conceptually the strategy is simple:  check to see whether the current
-+ * node matches, call self recursively to see whether the rest matches,
-+ * and then act accordingly.  In practice we make some effort to avoid
-+ * recursion, in particular by going through "ordinary" nodes (that don't
-+ * need to know whether the rest of the match failed) by a loop instead of
-+ * by recursion.
-+ */
-+static int                    /* 0 failure, 1 success */
-+regmatch(struct match_globals *g, char *prog)
-+{
-+      register char *scan = prog; /* Current node. */
-+      char *next;                 /* Next node. */
-+
-+#ifdef DEBUG
-+      if (scan != NULL && regnarrate)
-+              fprintf(stderr, "%s(\n", regprop(scan));
-+#endif
-+      while (scan != NULL) {
-+#ifdef DEBUG
-+              if (regnarrate)
-+                      fprintf(stderr, "%s...\n", regprop(scan));
-+#endif
-+              next = regnext(g, scan);
-+
-+              switch (OP(scan)) {
-+              case BOL:
-+                      if (g->reginput != g->regbol)
-+                              return(0);
-+                      break;
-+              case EOL:
-+                      if (*g->reginput != '\0')
-+                              return(0);
-+                      break;
-+              case ANY:
-+                      if (*g->reginput == '\0')
-+                              return(0);
-+                      g->reginput++;
-+                      break;
-+              case EXACTLY: {
-+                              register int len;
-+                              register char *opnd;
-+
-+                              opnd = OPERAND(scan);
-+                              /* Inline the first character, for speed. */
-+                              if (*opnd != *g->reginput)
-+                                      return(0);
-+                              len = strlen(opnd);
-+                              if (len > 1 && strncmp(opnd, g->reginput, len) != 0)
-+                                      return(0);
-+                              g->reginput += len;
-+                      }
-+                      break;
-+              case ANYOF:
-+                      if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) == NULL)
-+                              return(0);
-+                      g->reginput++;
-+                      break;
-+              case ANYBUT:
-+                      if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) != NULL)
-+                              return(0);
-+                      g->reginput++;
-+                      break;
-+              case NOTHING:
-+              case BACK:
-+                      break;
-+              case OPEN+1:
-+              case OPEN+2:
-+              case OPEN+3:
-+              case OPEN+4:
-+              case OPEN+5:
-+              case OPEN+6:
-+              case OPEN+7:
-+              case OPEN+8:
-+              case OPEN+9: {
-+                              register int no;
-+                              register char *save;
-+
-+                              no = OP(scan) - OPEN;
-+                              save = g->reginput;
-+
-+                              if (regmatch(g, next)) {
-+                                      /*
-+                                       * Don't set startp if some later
-+                                       * invocation of the same parentheses
-+                                       * already has.
-+                                       */
-+                                      if (g->regstartp[no] == NULL)
-+                                              g->regstartp[no] = save;
-+                                      return(1);
-+                              } else
-+                                      return(0);
-+                      }
-+                      break;
-+              case CLOSE+1:
-+              case CLOSE+2:
-+              case CLOSE+3:
-+              case CLOSE+4:
-+              case CLOSE+5:
-+              case CLOSE+6:
-+              case CLOSE+7:
-+              case CLOSE+8:
-+              case CLOSE+9:
-+                      {
-+                              register int no;
-+                              register char *save;
-+
-+                              no = OP(scan) - CLOSE;
-+                              save = g->reginput;
-+
-+                              if (regmatch(g, next)) {
-+                                      /*
-+                                       * Don't set endp if some later
-+                                       * invocation of the same parentheses
-+                                       * already has.
-+                                       */
-+                                      if (g->regendp[no] == NULL)
-+                                              g->regendp[no] = save;
-+                                      return(1);
-+                              } else
-+                                      return(0);
-+                      }
-+                      break;
-+              case BRANCH: {
-+                              register char *save;
-+
-+                              if (OP(next) != BRANCH)         /* No choice. */
-+                                      next = OPERAND(scan);   /* Avoid recursion. */
-+                              else {
-+                                      do {
-+                                              save = g->reginput;
-+                                              if (regmatch(g, OPERAND(scan)))
-+                                                      return(1);
-+                                              g->reginput = save;
-+                                              scan = regnext(g, scan);
-+                                      } while (scan != NULL && OP(scan) == BRANCH);
-+                                      return(0);
-+                                      /* NOTREACHED */
-+                              }
-+                      }
-+                      break;
-+              case STAR:
-+              case PLUS: {
-+                              register char nextch;
-+                              register int no;
-+                              register char *save;
-+                              register int min;
-+
-+                              /*
-+                               * Lookahead to avoid useless match attempts
-+                               * when we know what character comes next.
-+                               */
-+                              nextch = '\0';
-+                              if (OP(next) == EXACTLY)
-+                                      nextch = *OPERAND(next);
-+                              min = (OP(scan) == STAR) ? 0 : 1;
-+                              save = g->reginput;
-+                              no = regrepeat(g, OPERAND(scan));
-+                              while (no >= min) {
-+                                      /* If it could work, try it. */
-+                                      if (nextch == '\0' || *g->reginput == nextch)
-+                                              if (regmatch(g, next))
-+                                                      return(1);
-+                                      /* Couldn't or didn't -- back up. */
-+                                      no--;
-+                                      g->reginput = save + no;
-+                              }
-+                              return(0);
-+                      }
-+                      break;
-+              case END:
-+                      return(1);      /* Success! */
-+                      break;
-+              default:
-+                      printk("<3>Regexp: memory corruption\n");
-+                      return(0);
-+                      break;
-+              }
-+
-+              scan = next;
-+      }
-+
-+      /*
-+       * We get here only if there's trouble -- normally "case END" is
-+       * the terminating point.
-+       */
-+      printk("<3>Regexp: corrupted pointers\n");
-+      return(0);
-+}
-+
-+/*
-+ - regrepeat - repeatedly match something simple, report how many
-+ */
-+static int
-+regrepeat(struct match_globals *g, char *p)
-+{
-+      register int count = 0;
-+      register char *scan;
-+      register char *opnd;
-+
-+      scan = g->reginput;
-+      opnd = OPERAND(p);
-+      switch (OP(p)) {
-+      case ANY:
-+              count = strlen(scan);
-+              scan += count;
-+              break;
-+      case EXACTLY:
-+              while (*opnd == *scan) {
-+                      count++;
-+                      scan++;
-+              }
-+              break;
-+      case ANYOF:
-+              while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
-+                      count++;
-+                      scan++;
-+              }
-+              break;
-+      case ANYBUT:
-+              while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
-+                      count++;
-+                      scan++;
-+              }
-+              break;
-+      default:                /* Oh dear.  Called inappropriately. */
-+              printk("<3>Regexp: internal foulup\n");
-+              count = 0;      /* Best compromise. */
-+              break;
-+      }
-+      g->reginput = scan;
-+
-+      return(count);
-+}
-+
-+/*
-+ - regnext - dig the "next" pointer out of a node
-+ */
-+static char*
-+regnext(struct match_globals *g, char *p)
-+{
-+      register int offset;
-+
-+      if (p == &g->regdummy)
-+              return(NULL);
-+
-+      offset = NEXT(p);
-+      if (offset == 0)
-+              return(NULL);
-+
-+      if (OP(p) == BACK)
-+              return(p-offset);
-+      else
-+              return(p+offset);
-+}
-+
-+#ifdef DEBUG
-+
-+STATIC char *regprop();
-+
-+/*
-+ - regdump - dump a regexp onto stdout in vaguely comprehensible form
-+ */
-+void
-+regdump(regexp *r)
-+{
-+      register char *s;
-+      register char op = EXACTLY;     /* Arbitrary non-END op. */
-+      register char *next;
-+      /* extern char *strchr(); */
-+
-+
-+      s = r->program + 1;
-+      while (op != END) {     /* While that wasn't END last time... */
-+              op = OP(s);
-+              printf("%2d%s", s-r->program, regprop(s));      /* Where, what. */
-+              next = regnext(s);
-+              if (next == NULL)               /* Next ptr. */
-+                      printf("(0)");
-+              else
-+                      printf("(%d)", (s-r->program)+(next-s));
-+              s += 3;
-+              if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
-+                      /* Literal string, where present. */
-+                      while (*s != '\0') {
-+                              putchar(*s);
-+                              s++;
-+                      }
-+                      s++;
-+              }
-+              putchar('\n');
-+      }
-+
-+      /* Header fields of interest. */
-+      if (r->regstart != '\0')
-+              printf("start `%c' ", r->regstart);
-+      if (r->reganch)
-+              printf("anchored ");
-+      if (r->regmust != NULL)
-+              printf("must have \"%s\"", r->regmust);
-+      printf("\n");
-+}
-+
-+/*
-+ - regprop - printable representation of opcode
-+ */
-+static char *
-+regprop(char *op)
-+{
-+#define BUFLEN 50
-+      register char *p;
-+      static char buf[BUFLEN];
-+
-+      strcpy(buf, ":");
-+
-+      switch (OP(op)) {
-+      case BOL:
-+              p = "BOL";
-+              break;
-+      case EOL:
-+              p = "EOL";
-+              break;
-+      case ANY:
-+              p = "ANY";
-+              break;
-+      case ANYOF:
-+              p = "ANYOF";
-+              break;
-+      case ANYBUT:
-+              p = "ANYBUT";
-+              break;
-+      case BRANCH:
-+              p = "BRANCH";
-+              break;
-+      case EXACTLY:
-+              p = "EXACTLY";
-+              break;
-+      case NOTHING:
-+              p = "NOTHING";
-+              break;
-+      case BACK:
-+              p = "BACK";
-+              break;
-+      case END:
-+              p = "END";
-+              break;
-+      case OPEN+1:
-+      case OPEN+2:
-+      case OPEN+3:
-+      case OPEN+4:
-+      case OPEN+5:
-+      case OPEN+6:
-+      case OPEN+7:
-+      case OPEN+8:
-+      case OPEN+9:
-+              snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "OPEN%d", OP(op)-OPEN);
-+              p = NULL;
-+              break;
-+      case CLOSE+1:
-+      case CLOSE+2:
-+      case CLOSE+3:
-+      case CLOSE+4:
-+      case CLOSE+5:
-+      case CLOSE+6:
-+      case CLOSE+7:
-+      case CLOSE+8:
-+      case CLOSE+9:
-+              snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "CLOSE%d", OP(op)-CLOSE);
-+              p = NULL;
-+              break;
-+      case STAR:
-+              p = "STAR";
-+              break;
-+      case PLUS:
-+              p = "PLUS";
-+              break;
-+      default:
-+              printk("<3>Regexp: corrupted opcode\n");
-+              break;
-+      }
-+      if (p != NULL)
-+              strncat(buf, p, BUFLEN-strlen(buf));
-+      return(buf);
-+}
-+#endif
-+
-+
-diff -Naur linux-3.0.24.org/net/netfilter/regexp/regexp.h linux-3.0.24/net/netfilter/regexp/regexp.h
---- linux-3.0.24.org/net/netfilter/regexp/regexp.h     1970-01-01 01:00:00.000000000 +0100
-+++ linux-3.0.24/net/netfilter/regexp/regexp.h 2012-03-15 20:08:49.066043520 +0100
-@@ -0,0 +1,41 @@
-+/*
-+ * Definitions etc. for regexp(3) routines.
-+ *
-+ * Caveat:  this is V8 regexp(3) [actually, a reimplementation thereof],
-+ * not the System V one.
-+ */
-+
-+#ifndef REGEXP_H
-+#define REGEXP_H
-+
-+
-+/*
-+http://www.opensource.apple.com/darwinsource/10.3/expect-1/expect/expect.h ,
-+which contains a version of this library, says:
-+
-+ *
-+ * NSUBEXP must be at least 10, and no greater than 117 or the parser
-+ * will not work properly.
-+ *
-+
-+However, it looks rather like this library is limited to 10.  If you think
-+otherwise, let us know.
-+*/
-+
-+#define NSUBEXP  10
-+typedef struct regexp {
-+      char *startp[NSUBEXP];
-+      char *endp[NSUBEXP];
-+      char regstart;          /* Internal use only. */
-+      char reganch;           /* Internal use only. */
-+      char *regmust;          /* Internal use only. */
-+      int regmlen;            /* Internal use only. */
-+      char program[1];        /* Unwarranted chumminess with compiler. */
-+} regexp;
-+
-+regexp * regcomp(char *exp, int *patternsize);
-+int regexec(regexp *prog, char *string);
-+void regsub(regexp *prog, char *source, char *dest);
-+void regerror(char *s);
-+
-+#endif
-diff -Naur linux-3.0.24.org/net/netfilter/regexp/regmagic.h linux-3.0.24/net/netfilter/regexp/regmagic.h
---- linux-3.0.24.org/net/netfilter/regexp/regmagic.h   1970-01-01 01:00:00.000000000 +0100
-+++ linux-3.0.24/net/netfilter/regexp/regmagic.h       2012-03-15 20:08:49.066043520 +0100
-@@ -0,0 +1,5 @@
-+/*
-+ * The first byte of the regexp internal "program" is actually this magic
-+ * number; the start node begins in the second byte.
-+ */
-+#define       MAGIC   0234
-diff -Naur linux-3.0.24.org/net/netfilter/regexp/regsub.c linux-3.0.24/net/netfilter/regexp/regsub.c
---- linux-3.0.24.org/net/netfilter/regexp/regsub.c     1970-01-01 01:00:00.000000000 +0100
-+++ linux-3.0.24/net/netfilter/regexp/regsub.c 2012-03-15 20:08:49.076047746 +0100
-@@ -0,0 +1,95 @@
-+/*
-+ * regsub
-+ * @(#)regsub.c       1.3 of 2 April 86
-+ *
-+ *    Copyright (c) 1986 by University of Toronto.
-+ *    Written by Henry Spencer.  Not derived from licensed software.
-+ *
-+ *    Permission is granted to anyone to use this software for any
-+ *    purpose on any computer system, and to redistribute it freely,
-+ *    subject to the following restrictions:
-+ *
-+ *    1. The author is not responsible for the consequences of use of
-+ *            this software, no matter how awful, even if they arise
-+ *            from defects in it.
-+ *
-+ *    2. The origin of this software must not be misrepresented, either
-+ *            by explicit claim or by omission.
-+ *
-+ *    3. Altered versions must be plainly marked as such, and must not
-+ *            be misrepresented as being the original software.
-+ *
-+ *
-+ * This code was modified by Ethan Sommer to work within the kernel
-+ * (it now uses kmalloc etc..)
-+ *
-+ */
-+#include "regexp.h"
-+#include "regmagic.h"
-+#include <linux/string.h>
-+
-+
-+#ifndef CHARBITS
-+#define       UCHARAT(p)      ((int)*(unsigned char *)(p))
-+#else
-+#define       UCHARAT(p)      ((int)*(p)&CHARBITS)
-+#endif
-+
-+#if 0
-+//void regerror(char * s)
-+//{
-+//        printk("regexp(3): %s", s);
-+//        /* NOTREACHED */
-+//}
-+#endif
-+
-+/*
-+ - regsub - perform substitutions after a regexp match
-+ */
-+void
-+regsub(regexp * prog, char * source, char * dest)
-+{
-+      register char *src;
-+      register char *dst;
-+      register char c;
-+      register int no;
-+      register int len;
-+      
-+      /* Not necessary and gcc doesn't like it -MLS */
-+      /*extern char *strncpy();*/
-+
-+      if (prog == NULL || source == NULL || dest == NULL) {
-+              regerror("NULL parm to regsub");
-+              return;
-+      }
-+      if (UCHARAT(prog->program) != MAGIC) {
-+              regerror("damaged regexp fed to regsub");
-+              return;
-+      }
-+
-+      src = source;
-+      dst = dest;
-+      while ((c = *src++) != '\0') {
-+              if (c == '&')
-+                      no = 0;
-+              else if (c == '\\' && '0' <= *src && *src <= '9')
-+                      no = *src++ - '0';
-+              else
-+                      no = -1;
-+
-+              if (no < 0) {   /* Ordinary character. */
-+                      if (c == '\\' && (*src == '\\' || *src == '&'))
-+                              c = *src++;
-+                      *dst++ = c;
-+              } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
-+                      len = prog->endp[no] - prog->startp[no];
-+                      (void) strncpy(dst, prog->startp[no], len);
-+                      dst += len;
-+                      if (len != 0 && *(dst-1) == '\0') {     /* strncpy hit NUL. */
-+                              regerror("damaged match string");
-+                              return;
-+                      }
-+              }
-+      }
-+      *dst++ = '\0';
-+}
-diff -Naur linux-3.0.24.org/net/netfilter/xt_layer7.c linux-3.0.24/net/netfilter/xt_layer7.c
---- linux-3.0.24.org/net/netfilter/xt_layer7.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-3.0.24/net/netfilter/xt_layer7.c     2012-03-20 01:44:50.907527097 +0100
-@@ -0,0 +1,684 @@
-+/*
-+  Kernel module to match application layer (OSI layer 7) data in connections.
-+
-+  http://l7-filter.sf.net
-+
-+  (C) 2003-2009 Matthew Strait and Ethan Sommer.
-+
-+  This program is free software; you can redistribute it and/or
-+  modify it under the terms of the GNU General Public License
-+  as published by the Free Software Foundation; either version
-+  2 of the License, or (at your option) any later version.
-+  http://www.gnu.org/licenses/gpl.txt
-+
-+  Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be>,
-+  xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait,
-+  Ethan Sommer, Justin Levandoski.
-+*/
-+
-+#include <linux/spinlock.h>
-+#include <linux/version.h>
-+#include <net/ip.h>
-+#include <net/tcp.h>
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter.h>
-+#include <net/netfilter/nf_conntrack.h>
-+#include <net/netfilter/nf_conntrack_core.h>
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
-+#include <net/netfilter/nf_conntrack_extend.h>
-+#include <net/netfilter/nf_conntrack_acct.h>
-+#endif
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_layer7.h>
-+#include <linux/ctype.h>
-+#include <linux/proc_fs.h>
-+
-+#include "regexp/regexp.c"
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");
-+MODULE_DESCRIPTION("iptables application layer match module");
-+MODULE_ALIAS("ipt_layer7");
-+MODULE_VERSION("2.22ipfire");
-+
-+static int maxdatalen = 2048; // this is the default
-+module_param(maxdatalen, int, 0444);
-+MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter");
-+#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG
-+      #define DPRINTK(format,args...) printk(format,##args)
-+#else
-+      #define DPRINTK(format,args...)
-+#endif
-+
-+/* Number of packets whose data we look at.
-+This can be modified through /proc/net/layer7_numpackets */
-+static int num_packets = 10;
-+
-+static struct pattern_cache {
-+      char * regex_string;
-+      regexp * pattern;
-+      struct pattern_cache * next;
-+} * first_pattern_cache = NULL;
-+
-+DEFINE_SPINLOCK(l7_lock);
-+
-+static int total_acct_packets(struct nf_conn *ct)
-+{
-+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
-+      BUG_ON(ct == NULL);
-+      return (ct->counters[IP_CT_DIR_ORIGINAL].packets + ct->counters[IP_CT_DIR_REPLY].packets);
-+#else
-+      struct nf_conn_counter *acct;
-+
-+      BUG_ON(ct == NULL);
-+      acct = nf_conn_acct_find(ct);
-+      if (!acct)
-+              return 0;
-+      return (acct[IP_CT_DIR_ORIGINAL].packets + acct[IP_CT_DIR_REPLY].packets);
-+#endif
-+}
-+
-+#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
-+/* Converts an unfriendly string into a friendly one by
-+replacing unprintables with periods and all whitespace with " ". */
-+static char * friendly_print(unsigned char * s)
-+{
-+      char * f = kmalloc(strlen(s) + 1, GFP_ATOMIC);
-+      int i;
-+
-+      if(!f) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR "layer7: out of memory in "
-+                                      "friendly_print, bailing.\n");
-+              return NULL;
-+      }
-+
-+      for(i = 0; i < strlen(s); i++){
-+              if(isprint(s[i]) && s[i] < 128) f[i] = s[i];
-+              else if(isspace(s[i]))          f[i] = ' ';
-+              else                            f[i] = '.';
-+      }
-+      f[i] = '\0';
-+      return f;
-+}
-+
-+static char dec2hex(int i)
-+{
-+      switch (i) {
-+              case 0 ... 9:
-+                      return (i + '0');
-+                      break;
-+              case 10 ... 15:
-+                      return (i - 10 + 'a');
-+                      break;
-+              default:
-+                      if (net_ratelimit())
-+                              printk("layer7: Problem in dec2hex\n");
-+                      return '\0';
-+      }
-+}
-+
-+static char * hex_print(unsigned char * s)
-+{
-+      char * g = kmalloc(strlen(s)*3 + 1, GFP_ATOMIC);
-+      int i;
-+
-+      if(!g) {
-+             if (net_ratelimit())
-+                      printk(KERN_ERR "layer7: out of memory in hex_print, "
-+                                      "bailing.\n");
-+             return NULL;
-+      }
-+
-+      for(i = 0; i < strlen(s); i++) {
-+              g[i*3    ] = dec2hex(s[i]/16);
-+              g[i*3 + 1] = dec2hex(s[i]%16);
-+              g[i*3 + 2] = ' ';
-+      }
-+      g[i*3] = '\0';
-+
-+      return g;
-+}
-+#endif // DEBUG
-+
-+/* Use instead of regcomp.  As we expect to be seeing the same regexps over and
-+over again, it make sense to cache the results. */
-+static regexp * compile_and_cache(const char * regex_string, 
-+                                  const char * protocol)
-+{
-+      struct pattern_cache * node               = first_pattern_cache;
-+      struct pattern_cache * last_pattern_cache = first_pattern_cache;
-+      struct pattern_cache * tmp;
-+      unsigned int len;
-+
-+      while (node != NULL) {
-+              if (!strcmp(node->regex_string, regex_string))
-+              return node->pattern;
-+
-+              last_pattern_cache = node;/* points at the last non-NULL node */
-+              node = node->next;
-+      }
-+
-+      /* If we reach the end of the list, then we have not yet cached
-+         the pattern for this regex. Let's do that now.
-+         Be paranoid about running out of memory to avoid list corruption. */
-+      tmp = kmalloc(sizeof(struct pattern_cache), GFP_ATOMIC);
-+
-+      if(!tmp) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR "layer7: out of memory in "
-+                                      "compile_and_cache, bailing.\n");
-+              return NULL;
-+      }
-+
-+      tmp->regex_string  = kmalloc(strlen(regex_string) + 1, GFP_ATOMIC);
-+      tmp->pattern       = kmalloc(sizeof(struct regexp),    GFP_ATOMIC);
-+      tmp->next = NULL;
-+
-+      if(!tmp->regex_string || !tmp->pattern) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR "layer7: out of memory in "
-+                                      "compile_and_cache, bailing.\n");
-+              kfree(tmp->regex_string);
-+              kfree(tmp->pattern);
-+              kfree(tmp);
-+              return NULL;
-+      }
-+
-+      /* Ok.  The new node is all ready now. */
-+      node = tmp;
-+
-+      if(first_pattern_cache == NULL) /* list is empty */
-+              first_pattern_cache = node; /* make node the beginning */
-+      else
-+              last_pattern_cache->next = node; /* attach node to the end */
-+
-+      /* copy the string and compile the regex */
-+      len = strlen(regex_string);
-+      DPRINTK("layer7: about to compile this: \"%s\"\n", regex_string);
-+      node->pattern = regcomp((char *)regex_string, &len);
-+      if ( !node->pattern ) {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR "layer7: Error compiling regexp "
-+                                      "\"%s\" (%s)\n", 
-+                                      regex_string, protocol);
-+              /* pattern is now cached as NULL, so we won't try again. */
-+      }
-+
-+      strcpy(node->regex_string, regex_string);
-+      return node->pattern;
-+}
-+
-+static int can_handle(const struct sk_buff *skb)
-+{
-+      if(!ip_hdr(skb)) /* not IP */
-+              return 0;
-+      if(ip_hdr(skb)->protocol != IPPROTO_TCP &&
-+         ip_hdr(skb)->protocol != IPPROTO_UDP &&
-+         ip_hdr(skb)->protocol != IPPROTO_ICMP)
-+              return 0;
-+      return 1;
-+}
-+
-+/* Returns offset the into the skb->data that the application data starts */
-+static int app_data_offset(const struct sk_buff *skb)
-+{
-+      /* In case we are ported somewhere (ebtables?) where ip_hdr(skb)
-+      isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */
-+      int ip_hl = 4*ip_hdr(skb)->ihl;
-+
-+      if( ip_hdr(skb)->protocol == IPPROTO_TCP ) {
-+              /* 12 == offset into TCP header for the header length field.
-+              Can't get this with skb->h.th->doff because the tcphdr
-+              struct doesn't get set when routing (this is confirmed to be
-+              true in Netfilter as well as QoS.) */
-+              int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4);
-+
-+              return ip_hl + tcp_hl;
-+      } else if( ip_hdr(skb)->protocol == IPPROTO_UDP  ) {
-+              return ip_hl + 8; /* UDP header is always 8 bytes */
-+      } else if( ip_hdr(skb)->protocol == IPPROTO_ICMP ) {
-+              return ip_hl + 8; /* ICMP header is 8 bytes */
-+      } else {
-+              if (net_ratelimit())
-+                      printk(KERN_ERR "layer7: tried to handle unknown "
-+                                      "protocol!\n");
-+              return ip_hl + 8; /* something reasonable */
-+      }
-+}
-+
-+/* handles whether there's a match when we aren't appending data anymore */
-+static int match_no_append(struct nf_conn * conntrack, 
-+                           struct nf_conn * master_conntrack, 
-+                           enum ip_conntrack_info ctinfo,
-+                           enum ip_conntrack_info master_ctinfo,
-+                           const struct xt_layer7_info * info)
-+{
-+      /* If we're in here, throw the app data away */
-+      if(master_conntrack->layer7.app_data != NULL) {
-+
-+      #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
-+              if(!master_conntrack->layer7.app_proto) {
-+                      char * f = 
-+                        friendly_print(master_conntrack->layer7.app_data);
-+                      char * g = 
-+                        hex_print(master_conntrack->layer7.app_data);
-+                      DPRINTK("\nl7-filter gave up after %d bytes "
-+                              "(%d packets):\n%s\n",
-+                              strlen(f), total_acct_packets(master_conntrack), f);
-+                      kfree(f);
-+                      DPRINTK("In hex: %s\n", g);
-+                      kfree(g);
-+              }
-+      #endif
-+
-+              kfree(master_conntrack->layer7.app_data);
-+              master_conntrack->layer7.app_data = NULL; /* don't free again */
-+      }
-+
-+      if(master_conntrack->layer7.app_proto){
-+              /* Here child connections set their .app_proto (for /proc) */
-+              if(!conntrack->layer7.app_proto) {
-+                      conntrack->layer7.app_proto = 
-+                        kmalloc(strlen(master_conntrack->layer7.app_proto)+1, 
-+                          GFP_ATOMIC);
-+                      if(!conntrack->layer7.app_proto){
-+                              if (net_ratelimit())
-+                                      printk(KERN_ERR "layer7: out of memory "
-+                                                      "in match_no_append, "
-+                                                      "bailing.\n");
-+                              return 1;
-+                      }
-+                      strcpy(conntrack->layer7.app_proto, 
-+                              master_conntrack->layer7.app_proto);
-+              }
-+
-+              return (!strcmp(master_conntrack->layer7.app_proto, 
-+                              info->protocol));
-+      }
-+      else {
-+              /* If not classified, set to "unknown" to distinguish from
-+              connections that are still being tested. */
-+              master_conntrack->layer7.app_proto = 
-+                      kmalloc(strlen("unknown")+1, GFP_ATOMIC);
-+              if(!master_conntrack->layer7.app_proto){
-+                      if (net_ratelimit())
-+                              printk(KERN_ERR "layer7: out of memory in "
-+                                              "match_no_append, bailing.\n");
-+                      return 1;
-+              }
-+              strcpy(master_conntrack->layer7.app_proto, "unknown");
-+              return 0;
-+      }
-+}
-+
-+/* add the new app data to the conntrack.  Return number of bytes added. */
-+static int add_data(struct nf_conn * master_conntrack,
-+                    char * app_data, int appdatalen)
-+{
-+      int length = 0, i;
-+      int oldlength = master_conntrack->layer7.app_data_len;
-+
-+      /* This is a fix for a race condition by Deti Fliegl. However, I'm not 
-+         clear on whether the race condition exists or whether this really 
-+         fixes it.  I might just be being dense... Anyway, if it's not really 
-+         a fix, all it does is waste a very small amount of time. */
-+      if(!master_conntrack->layer7.app_data) return 0;
-+
-+      /* Strip nulls. Make everything lower case (our regex lib doesn't
-+      do case insensitivity).  Add it to the end of the current data. */
-+      for(i = 0; i < maxdatalen-oldlength-1 &&
-+                 i < appdatalen; i++) {
-+              if(app_data[i] != '\0') {
-+                      /* the kernel version of tolower mungs 'upper ascii' */
-+                      master_conntrack->layer7.app_data[length+oldlength] =
-+                              isascii(app_data[i])? 
-+                                      tolower(app_data[i]) : app_data[i];
-+                      length++;
-+              }
-+      }
-+
-+      master_conntrack->layer7.app_data[length+oldlength] = '\0';
-+      master_conntrack->layer7.app_data_len = length + oldlength;
-+
-+      return length;
-+}
-+
-+/* taken from drivers/video/modedb.c */
-+static int my_atoi(const char *s)
-+{
-+      int val = 0;
-+
-+      for (;; s++) {
-+              switch (*s) {
-+                      case '0'...'9':
-+                      val = 10*val+(*s-'0');
-+                      break;
-+              default:
-+                      return val;
-+              }
-+      }
-+}
-+
-+/* write out num_packets to userland. */
-+static int layer7_read_proc(char* page, char ** start, off_t off, int count,
-+                            int* eof, void * data)
-+{
-+      if(num_packets > 99 && net_ratelimit())
-+              printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n");
-+
-+      page[0] = num_packets/10 + '0';
-+      page[1] = num_packets%10 + '0';
-+      page[2] = '\n';
-+      page[3] = '\0';
-+
-+      *eof=1;
-+
-+      return 3;
-+}
-+
-+/* Read in num_packets from userland */
-+static int layer7_write_proc(struct file* file, const char* buffer,
-+                             unsigned long count, void *data)
-+{
-+      char * foo = kmalloc(count, GFP_ATOMIC);
-+
-+      if(!foo){
-+              if (net_ratelimit())
-+                      printk(KERN_ERR "layer7: out of memory, bailing. "
-+                                      "num_packets unchanged.\n");
-+              return count;
-+      }
-+
-+      if(copy_from_user(foo, buffer, count)) {
-+              return -EFAULT;
-+      }
-+
-+
-+      num_packets = my_atoi(foo);
-+      kfree (foo);
-+
-+      /* This has an arbitrary limit to make the math easier. I'm lazy.
-+      But anyway, 99 is a LOT! If you want more, you're doing it wrong! */
-+      if(num_packets > 99) {
-+              printk(KERN_WARNING "layer7: num_packets can't be > 99.\n");
-+              num_packets = 99;
-+      } else if(num_packets < 1) {
-+              printk(KERN_WARNING "layer7: num_packets can't be < 1.\n");
-+              num_packets = 1;
-+      }
-+
-+      return count;
-+}
-+
-+static bool
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
-+match(const struct sk_buff *skbin, struct xt_action_param *par)
-+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+match(const struct sk_buff *skbin, const struct xt_match_param *par)
-+#else
-+match(const struct sk_buff *skbin,
-+      const struct net_device *in,
-+      const struct net_device *out,
-+      const struct xt_match *match,
-+      const void *matchinfo,
-+      int offset,
-+      unsigned int protoff,
-+      bool *hotdrop)
-+#endif
-+{
-+      /* sidestep const without getting a compiler warning... */
-+      struct sk_buff * skb = (struct sk_buff *)skbin; 
-+
-+      const struct xt_layer7_info * info = 
-+      #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+              par->matchinfo;
-+      #else
-+              matchinfo;
-+      #endif
-+
-+      enum ip_conntrack_info master_ctinfo, ctinfo;
-+      struct nf_conn *master_conntrack, *conntrack;
-+      unsigned char * app_data;
-+      unsigned int pattern_result, appdatalen;
-+      regexp * comppattern;
-+
-+      /* Be paranoid/incompetent - lock the entire match function. */
-+      spin_lock_bh(&l7_lock);
-+
-+      if(!can_handle(skb)){
-+              DPRINTK("layer7: This is some protocol I can't handle.\n");
-+              spin_unlock_bh(&l7_lock);
-+              return info->invert;
-+      }
-+
-+      /* Treat parent & all its children together as one connection, except
-+      for the purpose of setting conntrack->layer7.app_proto in the actual
-+      connection. This makes /proc/net/ip_conntrack more satisfying. */
-+      if(!(conntrack = nf_ct_get(skb, &ctinfo)) ||
-+         !(master_conntrack=nf_ct_get(skb,&master_ctinfo))){
-+              DPRINTK("layer7: couldn't get conntrack.\n");
-+              spin_unlock_bh(&l7_lock);
-+              return info->invert;
-+      }
-+
-+      /* Try to get a master conntrack (and its master etc) for FTP, etc. */
-+      while (master_ct(master_conntrack) != NULL)
-+              master_conntrack = master_ct(master_conntrack);
-+
-+      /* if we've classified it or seen too many packets */
-+      if(total_acct_packets(master_conntrack) > num_packets ||
-+         master_conntrack->layer7.app_proto) {
-+
-+              pattern_result = match_no_append(conntrack, master_conntrack, 
-+                                               ctinfo, master_ctinfo, info);
-+
-+              /* skb->cb[0] == seen. Don't do things twice if there are 
-+              multiple l7 rules. I'm not sure that using cb for this purpose 
-+              is correct, even though it says "put your private variables 
-+              there". But it doesn't look like it is being used for anything
-+              else in the skbs that make it here. */
-+              skb->cb[0] = 1; /* marking it seen here's probably irrelevant */
-+
-+              spin_unlock_bh(&l7_lock);
-+              return (pattern_result ^ info->invert);
-+      }
-+
-+      if(skb_is_nonlinear(skb)){
-+              if(skb_linearize(skb) != 0){
-+                      if (net_ratelimit())
-+                              printk(KERN_ERR "layer7: failed to linearize "
-+                                              "packet, bailing.\n");
-+                      spin_unlock_bh(&l7_lock);
-+                      return info->invert;
-+              }
-+      }
-+
-+      /* now that the skb is linearized, it's safe to set these. */
-+      app_data = skb->data + app_data_offset(skb);
-+      appdatalen = skb_tail_pointer(skb) - app_data;
-+
-+      /* the return value gets checked later, when we're ready to use it */
-+      comppattern = compile_and_cache(info->pattern, info->protocol);
-+
-+      /* On the first packet of a connection, allocate space for app data */
-+      if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] && 
-+         !master_conntrack->layer7.app_data){
-+              master_conntrack->layer7.app_data = 
-+                      kmalloc(maxdatalen, GFP_ATOMIC);
-+              if(!master_conntrack->layer7.app_data){
-+                      if (net_ratelimit())
-+                              printk(KERN_ERR "layer7: out of memory in "
-+                                              "match, bailing.\n");
-+                      spin_unlock_bh(&l7_lock);
-+                      return info->invert;
-+              }
-+
-+              master_conntrack->layer7.app_data[0] = '\0';
-+      }
-+
-+      /* Can be here, but unallocated, if numpackets is increased near
-+      the beginning of a connection */
-+      if(master_conntrack->layer7.app_data == NULL){
-+              spin_unlock_bh(&l7_lock);
-+              return info->invert; /* unmatched */
-+      }
-+
-+      if(!skb->cb[0]){
-+              int newbytes;
-+              newbytes = add_data(master_conntrack, app_data, appdatalen);
-+
-+              if(newbytes == 0) { /* didn't add any data */
-+                      skb->cb[0] = 1;
-+                      /* Didn't match before, not going to match now */
-+                      spin_unlock_bh(&l7_lock);
-+                      return info->invert;
-+              }
-+      }
-+
-+      /* If looking for "unknown", then never match.  "Unknown" means that
-+      we've given up; we're still trying with these packets. */
-+      if(!strcmp(info->protocol, "unknown")) {
-+              pattern_result = 0;
-+      /* If looking for "unset", then always match. "Unset" means that we
-+      haven't yet classified the connection. */
-+      } else if(!strcmp(info->protocol, "unset")) {
-+              pattern_result = 2;
-+              DPRINTK("layer7: matched unset: not yet classified "
-+                      "(%d/%d packets)\n",
-+                        total_acct_packets(master_conntrack), num_packets);
-+      /* If the regexp failed to compile, don't bother running it */
-+      } else if(comppattern && 
-+                regexec(comppattern, master_conntrack->layer7.app_data)){
-+              DPRINTK("layer7: matched %s\n", info->protocol);
-+              pattern_result = 1;
-+      } else pattern_result = 0;
-+
-+      if(pattern_result == 1) {
-+              master_conntrack->layer7.app_proto = 
-+                      kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);
-+              if(!master_conntrack->layer7.app_proto){
-+                      if (net_ratelimit())
-+                              printk(KERN_ERR "layer7: out of memory in "
-+                                              "match, bailing.\n");
-+                      spin_unlock_bh(&l7_lock);
-+                      return (pattern_result ^ info->invert);
-+              }
-+              strcpy(master_conntrack->layer7.app_proto, info->protocol);
-+      } else if(pattern_result > 1) { /* cleanup from "unset" */
-+              pattern_result = 1;
-+      }
-+
-+      /* mark the packet seen */
-+      skb->cb[0] = 1;
-+
-+      spin_unlock_bh(&l7_lock);
-+      return (pattern_result ^ info->invert);
-+}
-+
-+// load nf_conntrack_ipv4
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
-+static int
-+#else
-+static bool
-+#endif
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+check(const struct xt_mtchk_param *par)
-+{
-+        if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
-+                printk(KERN_WARNING "can't load conntrack support for "
-+                                    "proto=%d\n", par->match->family);
-+#else
-+check(const char *tablename, const void *inf,
-+               const struct xt_match *match, void *matchinfo,
-+               unsigned int hook_mask)
-+{
-+        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
-+                printk(KERN_WARNING "can't load conntrack support for "
-+                                    "proto=%d\n", match->family);
-+#endif
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
-+              return -EINVAL;
-+      }
-+      return 0;
-+#else
-+                return 0;
-+        }
-+      return 1;
-+#endif
-+}
-+
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+      static void destroy(const struct xt_mtdtor_param *par)
-+      {
-+              nf_ct_l3proto_module_put(par->match->family);
-+      }
-+#else
-+      static void destroy(const struct xt_match *match, void *matchinfo)
-+      {
-+              nf_ct_l3proto_module_put(match->family);
-+      }
-+#endif
-+
-+static struct xt_match xt_layer7_match[] __read_mostly = {
-+{
-+      .name           = "layer7",
-+      .family         = AF_INET,
-+      .checkentry     = check,
-+      .match          = match,
-+      .destroy        = destroy,
-+      .matchsize      = sizeof(struct xt_layer7_info),
-+      .me             = THIS_MODULE
-+}
-+};
-+
-+static void layer7_cleanup_proc(void)
-+{
-+      remove_proc_entry("layer7_numpackets", init_net.proc_net);
-+}
-+
-+/* register the proc file */
-+static void layer7_init_proc(void)
-+{
-+      struct proc_dir_entry* entry;
-+      entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net);
-+      entry->read_proc = layer7_read_proc;
-+      entry->write_proc = layer7_write_proc;
-+}
-+
-+static int __init xt_layer7_init(void)
-+{
-+      need_conntrack();
-+
-+      if (init_net.ct.sysctl_acct == 0) {
-+              printk(KERN_WARNING "layer7: enabling nf_conntrack_acct\n");
-+              init_net.ct.sysctl_acct = 1;
-+      }
-+
-+      layer7_init_proc();
-+      if(maxdatalen < 1) {
-+              printk(KERN_WARNING "layer7: maxdatalen can't be < 1, "
-+                      "using 1\n");
-+              maxdatalen = 1;
-+      }
-+      /* This is not a hard limit.  It's just here to prevent people from
-+      bringing their slow machines to a grinding halt. */
-+      else if(maxdatalen > 65536) {
-+              printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, "
-+                      "using 65536\n");
-+              maxdatalen = 65536;
-+      }
-+      return xt_register_matches(xt_layer7_match,
-+                                 ARRAY_SIZE(xt_layer7_match));
-+}
-+
-+static void __exit xt_layer7_fini(void)
-+{
-+      layer7_cleanup_proc();
-+      xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match));
-+}
-+
-+module_init(xt_layer7_init);
-+module_exit(xt_layer7_fini);
diff --git a/src/patches/openssl-0.9.8n-cryptodev.diff b/src/patches/openssl-0.9.8n-cryptodev.diff
deleted file mode 100644 (file)
index 0913f9a..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-diff -Naur openssl-0.9.8n.org/crypto/engine/eng_all.c openssl-0.9.8n/crypto/engine/eng_all.c
---- openssl-0.9.8n.org/crypto/engine/eng_all.c 2010-03-01 01:30:11.000000000 +0100
-+++ openssl-0.9.8n/crypto/engine/eng_all.c     2010-03-30 08:11:26.000000000 +0200
-@@ -104,16 +104,13 @@
- #endif
- #endif
- #ifndef OPENSSL_NO_HW
--#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
-       ENGINE_load_cryptodev();
--#endif
- #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
-       ENGINE_load_capi();
- #endif
- #endif
-       }
--#if defined(__OpenBSD__) || defined(__FreeBSD__)
- void ENGINE_setup_bsd_cryptodev(void) {
-       static int bsd_cryptodev_default_loaded = 0;
-       if (!bsd_cryptodev_default_loaded) {
-@@ -122,4 +119,3 @@
-       }
-       bsd_cryptodev_default_loaded=1;
- }
--#endif
-diff -Naur openssl-0.9.8n.org/crypto/engine/eng_cryptodev.c openssl-0.9.8n/crypto/engine/eng_cryptodev.c
---- openssl-0.9.8n.org/crypto/engine/eng_cryptodev.c   2010-03-03 16:30:05.000000000 +0100
-+++ openssl-0.9.8n/crypto/engine/eng_cryptodev.c       2010-03-30 08:01:11.000000000 +0200
-@@ -38,14 +38,15 @@
- #if (defined(__unix__) || defined(unix)) && !defined(USG) && \
-       (defined(OpenBSD) || defined(__FreeBSD__))
- #include <sys/param.h>
--# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
--#  define HAVE_CRYPTODEV
--# endif
- # if (OpenBSD >= 200110)
- #  define HAVE_SYSLOG_R
- # endif
- #endif
-+#if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) || defined(__linux__)
-+# define HAVE_CRYPTODEV
-+#endif
-+
- #ifndef HAVE_CRYPTODEV
- void
-@@ -58,7 +59,12 @@
- #else 
-  
- #include <sys/types.h>
--#include <crypto/cryptodev.h>
-+#if defined(__linux__)
-+# include <linux/cryptodev.h>
-+# define HAVE_CRYPTODEV_NAME
-+#else
-+# include <crypto/cryptodev.h>
-+#endif
- #include <sys/ioctl.h>
- #include <errno.h>
- #include <stdio.h>
-@@ -81,7 +87,11 @@
- static int get_dev_crypto(void);
- static int cryptodev_max_iv(int cipher);
- static int cryptodev_key_length_valid(int cipher, int len);
--static int cipher_nid_to_cryptodev(int nid);
-+#ifndef HAVE_CRYPTODEV_NAME
-+ static int cipher_nid_to_cryptodev(int nid);
-+#else
-+ static char *cipher_nid_to_cryptodev_name(int nid);
-+#endif
- static int get_cryptodev_ciphers(const int **cnids);
- /*static int get_cryptodev_digests(const int **cnids);*/
- static int cryptodev_usable_ciphers(const int **nids);
-diff -Naur openssl-0.9.8n.org/crypto/engine/engine.h openssl-0.9.8n/crypto/engine/engine.h
---- openssl-0.9.8n.org/crypto/engine/engine.h  2010-02-09 15:18:15.000000000 +0100
-+++ openssl-0.9.8n/crypto/engine/engine.h      2010-03-30 08:01:11.000000000 +0200
-@@ -705,9 +705,7 @@
-  * values. */
- void *ENGINE_get_static_state(void);
--#if defined(__OpenBSD__) || defined(__FreeBSD__)
- void ENGINE_setup_bsd_cryptodev(void);
--#endif
- /* BEGIN ERROR CODES */
- /* The following lines are auto generated by the script mkerr.pl. Any changes
-diff -Naur openssl-0.9.8n.org/crypto/evp/c_all.c openssl-0.9.8n/crypto/evp/c_all.c
---- openssl-0.9.8n.org/crypto/evp/c_all.c      2004-08-29 18:36:04.000000000 +0200
-+++ openssl-0.9.8n/crypto/evp/c_all.c  2010-03-30 08:01:11.000000000 +0200
-@@ -83,8 +83,6 @@
-       OpenSSL_add_all_ciphers();
-       OpenSSL_add_all_digests();
- #ifndef OPENSSL_NO_ENGINE
--# if defined(__OpenBSD__) || defined(__FreeBSD__)
-       ENGINE_setup_bsd_cryptodev();
--# endif
- #endif
-       }
diff --git a/src/patches/pciutils-2.1.10-scan.patch b/src/patches/pciutils-2.1.10-scan.patch
deleted file mode 100644 (file)
index 590c21d..0000000
+++ /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 (file)
index 43257d5..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Patch by Robert Scheck <redhat@linuxnetz.de> for pciutils >= 2.1.99, which make pciutils
-rebuildable using gcc 4.
-
---- pciutils-2.1.99-test8/lib/i386-ports.c             2004-08-13 22:13:11.000000000 +0200
-+++ pciutils-2.1.99-test8/lib/i386-ports.c.gcc4                2005-03-14 09:30:06.000000000 +0100
-@@ -57,9 +57,9 @@
-   for(d.dev = 0; d.dev < 32; d.dev++)
-     {
-       u16 class, vendor;
--      if (m->read(&d, PCI_CLASS_DEVICE, (byte *) &class, sizeof(class)) &&
-+      if ((m->read) (&d, PCI_CLASS_DEVICE, (byte *) &class, sizeof(class)) &&
-         (class == cpu_to_le16(PCI_CLASS_BRIDGE_HOST) || class == cpu_to_le16(PCI_CLASS_DISPLAY_VGA)) ||
--        m->read(&d, PCI_VENDOR_ID, (byte *) &vendor, sizeof(vendor)) &&
-+        (m->read) (&d, PCI_VENDOR_ID, (byte *) &vendor, sizeof(vendor)) &&
-         (vendor == cpu_to_le16(PCI_VENDOR_ID_INTEL) || vendor == cpu_to_le16(PCI_VENDOR_ID_COMPAQ)))
-       {
-         a->debug("...outside the Asylum at 0/%02x/0", d.dev);
diff --git a/src/patches/pciutils-2.2.1-idpath.patch b/src/patches/pciutils-2.2.1-idpath.patch
deleted file mode 100644 (file)
index 62b57f0..0000000
+++ /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 (file)
index 789dee5..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
---- pciutils-2.2.3/lib/configure.multilib      2006-05-05 14:25:07.000000000 +0200
-+++ pciutils-2.2.3/lib/configure       2006-05-23 15:50:16.000000000 +0200
-@@ -30,8 +30,37 @@
- echo " $host $rel"
- c=config.h
--echo >$c "#define PCI_ARCH_`echo $cpu | tr 'a-z' 'A-Z'`"
--echo >>$c "#define PCI_OS_`echo $sys | tr 'a-z' 'A-Z'`"
-+cm=config.h.mk
-+cat >$c <<EOF
-+#if defined(__x86_64__)
-+#define PCI_ARCH_X86_64
-+#elif defined(__ia64__)
-+#define PCI_ARCH_IA64
-+#elif defined(__i386__)
-+#define PCI_ARCH_I386
-+#define PCI_HAVE_PM_INTEL_CONF
-+#elif defined(__ppc64__) || defined(__powerpc64__)
-+#define PCI_ARCH_PPC64
-+#elif defined(__ppc__)  || defined(__powerpc__)
-+#define PCI_ARCH_PPC
-+#elif defined(__s390x__)
-+#define PCI_ARCH_S390X
-+#elif defined(__s390__)
-+#define PCI_ARCH_S390
-+#else
-+#error Unknown Arch
-+#endif
-+#define PCI_OS_LINUX
-+#define PCI_HAVE_PM_LINUX_SYSFS
-+#define PCI_HAVE_PM_LINUX_PROC
-+#define PCI_HAVE_LINUX_BYTEORDER_H
-+#define PCI_PATH_PROC_BUS_PCI "/proc/bus/pci"
-+#define PCI_PATH_SYS_BUS_PCI "/sys/bus/pci"
-+#define PCI_HAVE_64BIT_ADDRESS
-+EOF
-+
-+echo >$cm "#define PCI_ARCH_`echo $cpu | tr 'a-z' 'A-Z'`"
-+echo >>$cm "#define PCI_OS_`echo $sys | tr 'a-z' 'A-Z'`"
- echo_n "Looking for access methods..."
-@@ -39,63 +68,22 @@
-       linux*)
-               case $rel in
-                       2.[1-9]*|[3-9]*)        echo_n " sysfs proc"
--                                              echo >>$c '#define PCI_HAVE_PM_LINUX_SYSFS'
--                                              echo >>$c '#define PCI_HAVE_PM_LINUX_PROC'
--                                              echo >>$c '#define PCI_HAVE_LINUX_BYTEORDER_H'
--                                              echo >>$c '#define PCI_PATH_PROC_BUS_PCI "/proc/bus/pci"'
--                                              echo >>$c '#define PCI_PATH_SYS_BUS_PCI "/sys/bus/pci"'
--                                              ok=1
--                                              ;;
--              esac
--              case $cpu in
--                              i386)           echo_n " i386-ports"
--                                              echo >>$c '#define PCI_HAVE_PM_INTEL_CONF'
-+                                              echo >>$cm '#define PCI_HAVE_PM_LINUX_SYSFS'
-+                                              echo >>$cm '#define PCI_HAVE_PM_LINUX_PROC'
-+                                              echo >>$cm '#define PCI_HAVE_LINUX_BYTEORDER_H'
-+                                              echo >>$cm '#define PCI_PATH_PROC_BUS_PCI "/proc/bus/pci"'
-+                                              echo >>$cm '#define PCI_PATH_SYS_BUS_PCI "/sys/bus/pci"'
-                                               ok=1
-                                               ;;
-               esac
--              echo >>$c '#define PCI_HAVE_64BIT_ADDRESS'
--              ;;
--      sunos)
-               case $cpu in
-                               i386)           echo_n " i386-ports"
--                                              echo >>$c "#define PCI_HAVE_PM_INTEL_CONF"
-+                                              echo >>$cm '#define PCI_HAVE_PM_INTEL_CONF'
-                                               ok=1
-                                               ;;
--                              *)
--                                              echo " The PCI library is does not support Solaris for this architecture: $cpu"
--                                              exit 1
--                                              ;;
-               esac
--              ;;
--              
--      freebsd)
--              echo_n " fbsd-device"
--              echo >>$c '#define PCI_HAVE_PM_FBSD_DEVICE'
--              echo >>$c '#define PCI_PATH_FBSD_DEVICE "/dev/pci"'
--              ok=1
--              ;;
--        openbsd)
--              echo_n " obsd-device"
--              echo >>$c '#define PCI_HAVE_PM_OBSD_DEVICE'
--              echo >>$c '#define PCI_PATH_OBSD_DEVICE "/dev/pci"'
--              ok=1
--              ;;
--      aix)
--              echo_n " aix-device"
--              echo >>$c '#define PCI_HAVE_PM_AIX_DEVICE'
--              ok=1
--              ;;
--      netbsd)
--              echo_n " nbsd-libpci"
--              echo >>$c '#define PCI_HAVE_PM_NBSD_LIBPCI'
--              echo >>$c '#define PCI_PATH_NBSD_DEVICE "/dev/pci0"'
--              ok=1
--              ;;
--      gnu)
--              echo_n " i386-ports"
--              echo >>$c '#define PCI_HAVE_PM_INTEL_CONF'
--              ok=1
--              ;;
-+              echo >>$cm '#define PCI_HAVE_64BIT_ADDRESS'
-+              ;;              
-         *)
-               echo " Unfortunately, your OS is not supported by the PCI Library"
-               exit 1
-@@ -103,10 +91,14 @@
- esac
- echo >>$c '#define PCI_HAVE_PM_DUMP'
-+echo >>$cm '#define PCI_HAVE_PM_DUMP'
- echo " dump"
- if [ -z "$ok" ] ; then
-       echo "WARNING: No real configuration access method is available."
- fi
- echo >>$c "#define PCI_PATH_IDS \"$idsdir/pci.ids\""
- echo >>$c "#define PCILIB_VERSION \"$version\""
--sed '/^#define [^ ]*$/!d;s/^#define \(.*\)/\1=1/' <$c >config.mk
-+
-+echo >>$cm "#define PCI_PATH_IDS \"$idsdir/pci.ids\""
-+echo >>$cm "#define PCILIB_VERSION \"$version\""
-+sed '/^#define [^ ]*$/!d;s/^#define \(.*\)/\1=1/' <$cm >config.mk
diff --git a/src/patches/pciutils-2.2.3-sata.patch b/src/patches/pciutils-2.2.3-sata.patch
deleted file mode 100644 (file)
index 14f9f5e..0000000
+++ /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 (file)
index 87e45b4..0000000
+++ /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 (file)
index 56fbff3..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
---- pciutils-2.1.99-test8/lib/pread.h.pread    2004-08-13 16:15:46.000000000 -0400
-+++ pciutils-2.1.99-test8/lib/pread.h  2004-08-31 00:30:03.168157294 -0400
-@@ -12,54 +12,6 @@
-  *  don't define it.
-  */
--#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0
--/* glibc 2.1 or newer -> pread/pwrite supported automatically */
--
--#elif defined(i386) && defined(__GLIBC__)
--/* glibc 2.0 on i386 -> call syscalls directly */
--#include <asm/unistd.h>
--#include <syscall-list.h>
--#ifndef SYS_pread
--#define SYS_pread 180
--#endif
--static int pread(unsigned int fd, void *buf, size_t size, loff_t where)
--{ return syscall(SYS_pread, fd, buf, size, where); }
--#ifndef SYS_pwrite
--#define SYS_pwrite 181
--#endif
--static int pwrite(unsigned int fd, void *buf, size_t size, loff_t where)
--{ return syscall(SYS_pwrite, fd, buf, size, where); }
--
--#elif defined(i386)
--/* old libc on i386 -> call syscalls directly the old way */
--#include <asm/unistd.h>
--static _syscall5(int, pread, unsigned int, fd, void *, buf, size_t, size, u32, where_lo, u32, where_hi);
--static _syscall5(int, pwrite, unsigned int, fd, void *, buf, size_t, size, u32, where_lo, u32, where_hi);
--static int do_read(struct pci_dev *d UNUSED, int fd, void *buf, size_t size, int where) { return pread(fd, buf, size, where, 0); }
--static int do_write(struct pci_dev *d UNUSED, int fd, void *buf, size_t size, int where) { return pwrite(fd, buf, size, where, 0); }
--#define PCI_HAVE_DO_READ
--
--#else
--/* In all other cases we use lseek/read/write instead to be safe */
--#define make_rw_glue(op) \
--      static int do_##op(struct pci_dev *d, int fd, void *buf, size_t size, int where)        \
--      {                                                                                       \
--        struct pci_access *a = d->access;                                                     \
--        int r;                                                                                \
--        if (a->fd_pos != where && lseek(fd, where, SEEK_SET) < 0)                             \
--          return -1;                                                                          \
--        r = op(fd, buf, size);                                                                \
--        if (r < 0)                                                                            \
--          a->fd_pos = -1;                                                                     \
--        else                                                                                  \
--          a->fd_pos = where + r;                                                              \
--        return r;                                                                             \
--      }
--make_rw_glue(read)
--make_rw_glue(write)
--#define PCI_HAVE_DO_READ
--#endif
--
- #ifndef PCI_HAVE_DO_READ
- #define do_read(d,f,b,l,p) pread(f,b,l,p)
- #define do_write(d,f,b,l,p) pwrite(f,b,l,p)
diff --git a/src/patches/pciutils-strip.patch b/src/patches/pciutils-strip.patch
deleted file mode 100644 (file)
index 19ca22e..0000000
+++ /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 (file)
index 9dceebc..0000000
+++ /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 (file)
index 36905d0..0000000
+++ /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 (file)
index 68e2767..0000000
+++ /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 (file)
index 31dde45..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-diff -Naur qemu-0.14.1.org/hw/virtio-9p-local.c qemu-0.14.1/hw/virtio-9p-local.c
---- qemu-0.14.1.org/hw/virtio-9p-local.c       2011-05-06 21:01:43.000000000 +0200
-+++ qemu-0.14.1/hw/virtio-9p-local.c   2011-05-18 14:04:32.432444320 +0200
-@@ -10,6 +10,7 @@
-  * the COPYING file in the top-level directory.
-  *
-  */
-+
- #include "virtio.h"
- #include "virtio-9p.h"
- #include "virtio-9p-xattr.h"
-@@ -20,6 +21,16 @@
- #include <sys/un.h>
- #include <attr/xattr.h>
-+#ifndef AT_FDCWD
-+/* Copied from linux/include/linux/fcntl.h * because direct include fails */
-+#define AT_FDCWD              -100    /* Special value used to indicate
-+                                           openat should use the current
-+                                           working directory. */
-+#define AT_SYMLINK_NOFOLLOW   0x100   /* Do not follow symbolic links.  */
-+#define AT_REMOVEDIR          0x200   /* Remove directory instead of
-+                                           unlinking file.  */
-+#define AT_SYMLINK_FOLLOW     0x400   /* Follow symbolic links.  */
-+#endif
- static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
- {
diff --git a/src/patches/r8101_add_missing_pciids.patch b/src/patches/r8101_add_missing_pciids.patch
deleted file mode 100644 (file)
index a065493..0000000
+++ /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 (file)
index 86916f6..0000000
+++ /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 (file)
index 5bb4db2..0000000
+++ /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 (file)
index 77072ce..0000000
+++ /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 (file)
index fcc5009..0000000
+++ /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 (file)
index e3ac8d2..0000000
+++ /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<nibble.max@gmail.com>
-+    Copyright (C) 2010 Montage Technology<www.montage-tech.com>
-+    Copyright (C) 2009 Konstantin Dimitrov.
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/init.h>
-+#include <linux/firmware.h>
-+
-+#include "dvb_frontend.h"
-+#include "m88ds3103.h"
-+#include "m88ds3103_priv.h"
-+
-+static int debug;
-+module_param(debug, int, 0644);
-+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-+
-+#define dprintk(args...) \
-+      do { \
-+              if (debug) \
-+                      printk(KERN_INFO "m88ds3103: " args); \
-+      } while (0)
-+
-+/*demod register operations.*/
-+static int m88ds3103_writereg(struct m88ds3103_state *state, int reg, int data)
-+{
-+      u8 buf[] = { reg, data };
-+      struct i2c_msg msg = { .addr = state->config->demod_address,
-+              .flags = 0, .buf = buf, .len = 2 };
-+      int err;
-+
-+      if (debug > 1)
-+              printk("m88ds3103: %s: write reg 0x%02x, value 0x%02x\n",
-+                      __func__, reg, data);
-+
-+      err = i2c_transfer(state->i2c, &msg, 1);
-+      if (err != 1) {
-+              printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
-+                       " value == 0x%02x)\n", __func__, err, reg, data);
-+              return -EREMOTEIO;
-+      }
-+      return 0;
-+}
-+
-+static int m88ds3103_readreg(struct m88ds3103_state *state, u8 reg)
-+{
-+      int ret;
-+      u8 b0[] = { reg };
-+      u8 b1[] = { 0 };
-+      struct i2c_msg msg[] = {
-+              { .addr = state->config->demod_address, .flags = 0,
-+                      .buf = b0, .len = 1 },
-+              { .addr = state->config->demod_address, .flags = I2C_M_RD,
-+                      .buf = b1, .len = 1 }
-+      };
-+      ret = i2c_transfer(state->i2c, msg, 2);
-+
-+      if (ret != 2) {
-+              printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
-+                      __func__, reg, ret);
-+              return ret;
-+      }
-+
-+      if (debug > 1)
-+              printk(KERN_INFO "m88ds3103: read reg 0x%02x, value 0x%02x\n",
-+                      reg, b1[0]);
-+
-+      return b1[0];
-+}
-+
-+/*tuner register operations.*/
-+static int m88ds3103_tuner_writereg(struct m88ds3103_state *state, int reg, int data)
-+{
-+      u8 buf[] = { reg, data };
-+      struct i2c_msg msg = { .addr = 0x60,
-+              .flags = 0, .buf = buf, .len = 2 };
-+      int err;
-+
-+      m88ds3103_writereg(state, 0x03, 0x11);
-+      err = i2c_transfer(state->i2c, &msg, 1);
-+      
-+      if (err != 1) {
-+              printk("%s: writereg error(err == %i, reg == 0x%02x,"
-+                       " value == 0x%02x)\n", __func__, err, reg, data);
-+              return -EREMOTEIO;
-+      }
-+
-+      return 0;
-+}
-+
-+static int m88ds3103_tuner_readreg(struct m88ds3103_state *state, u8 reg)
-+{
-+      int ret;
-+      u8 b0[] = { reg };
-+      u8 b1[] = { 0 };
-+      struct i2c_msg msg[] = {
-+              { .addr = 0x60, .flags = 0,
-+                      .buf = b0, .len = 1 },
-+              { .addr = 0x60, .flags = I2C_M_RD,
-+                      .buf = b1, .len = 1 }
-+      };
-+
-+      m88ds3103_writereg(state, 0x03, 0x11);  
-+      ret = i2c_transfer(state->i2c, msg, 2);
-+
-+      if (ret != 2) {
-+              printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
-+              return ret;
-+      }
-+
-+      return b1[0];
-+}
-+
-+/* Bulk demod I2C write, for firmware download. */
-+static int m88ds3103_writeregN(struct m88ds3103_state *state, int reg,
-+                              const u8 *data, u16 len)
-+{
-+      int ret = -EREMOTEIO;
-+      struct i2c_msg msg;
-+      u8 *buf;
-+
-+      buf = kmalloc(len + 1, GFP_KERNEL);
-+      if (buf == NULL) {
-+              printk("Unable to kmalloc\n");
-+              ret = -ENOMEM;
-+              goto error;
-+      }
-+
-+      *(buf) = reg;
-+      memcpy(buf + 1, data, len);
-+
-+      msg.addr = state->config->demod_address;
-+      msg.flags = 0;
-+      msg.buf = buf;
-+      msg.len = len + 1;
-+
-+      if (debug > 1)
-+              printk(KERN_INFO "m88ds3103: %s:  write regN 0x%02x, len = %d\n",
-+                      __func__, reg, len);
-+
-+      ret = i2c_transfer(state->i2c, &msg, 1);
-+      if (ret != 1) {
-+              printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
-+                       __func__, ret, reg);
-+              ret = -EREMOTEIO;
-+      }
-+      
-+error:
-+      kfree(buf);
-+
-+      return ret;
-+}
-+
-+static int m88ds3103_load_firmware(struct dvb_frontend *fe)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      const struct firmware *fw;
-+      int i, ret = 0;
-+
-+      dprintk("%s()\n", __func__);
-+              
-+      if (state->skip_fw_load)
-+              return 0;
-+      /* Load firmware */
-+      /* request the firmware, this will block until someone uploads it */    
-+      if(state->demod_id == DS3000_ID){
-+              printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
-+                              DS3000_DEFAULT_FIRMWARE);               
-+              ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
-+                                      state->i2c->dev.parent);
-+      }else if(state->demod_id == DS3103_ID){
-+              printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
-+                              DS3103_DEFAULT_FIRMWARE);
-+              ret = request_firmware(&fw, DS3103_DEFAULT_FIRMWARE,
-+                                      state->i2c->dev.parent);
-+      }
-+      
-+      printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
-+      if (ret) {
-+              printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
-+                              "found?)\n", __func__);
-+              return ret;
-+      }
-+
-+      /* Make sure we don't recurse back through here during loading */
-+      state->skip_fw_load = 1;
-+
-+      dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
-+                      fw->size,
-+                      fw->data[0],
-+                      fw->data[1],
-+                      fw->data[fw->size - 2],
-+                      fw->data[fw->size - 1]);
-+                      
-+      /* stop internal mcu. */
-+      m88ds3103_writereg(state, 0xb2, 0x01);
-+      /* split firmware to download.*/
-+      for(i = 0; i < FW_DOWN_LOOP; i++){
-+              ret = m88ds3103_writeregN(state, 0xb0, &(fw->data[FW_DOWN_SIZE*i]), FW_DOWN_SIZE);
-+              if(ret != 1) break;             
-+      }
-+      /* start internal mcu. */
-+      if(ret == 1)
-+              m88ds3103_writereg(state, 0xb2, 0x00);
-+              
-+      release_firmware(fw);
-+
-+      dprintk("%s: Firmware upload %s\n", __func__,
-+                      ret == 1 ? "complete" : "failed");
-+
-+      if(ret == 1) ret = 0;
-+      
-+      /* Ensure firmware is always loaded if required */
-+      state->skip_fw_load = 0;
-+
-+      return ret;
-+}
-+
-+
-+static int m88ds3103_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      u8 data;
-+
-+      dprintk("%s(%d)\n", __func__, voltage);
-+
-+      dprintk("m88ds3103:pin_ctrl = (%02x)\n", state->config->pin_ctrl);
-+      
-+      if(state->config->set_voltage)
-+              state->config->set_voltage(fe, voltage);
-+      
-+      data = m88ds3103_readreg(state, 0xa2);
-+      
-+        if(state->config->pin_ctrl & 0x80){ /*If control pin is assigned.*/
-+              data &= ~0x03; /* bit0 V/H, bit1 off/on */
-+              if(state->config->pin_ctrl & 0x02)
-+                   data |= 0x02;
-+
-+              switch (voltage) {
-+              case SEC_VOLTAGE_18:
-+                   if((state->config->pin_ctrl & 0x01) == 0)
-+                        data |= 0x01;
-+                   break;
-+              case SEC_VOLTAGE_13:
-+                   if(state->config->pin_ctrl & 0x01)
-+                        data |= 0x01;
-+                   break;
-+              case SEC_VOLTAGE_OFF:
-+                   if(state->config->pin_ctrl & 0x02)
-+                         data &= ~0x02;                       
-+                   else
-+                         data |= 0x02;
-+                   break;
-+               }
-+        }
-+
-+      m88ds3103_writereg(state, 0xa2, data);
-+
-+      return 0;
-+}
-+
-+static int m88ds3103_read_status(struct dvb_frontend *fe, fe_status_t* status)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      int lock = 0;
-+      
-+      *status = 0;
-+      
-+      switch (state->delivery_system){
-+      case SYS_DVBS:
-+              lock = m88ds3103_readreg(state, 0xd1);
-+              dprintk("%s: SYS_DVBS status=%x.\n", __func__, lock);
-+              
-+              if ((lock & 0x07) == 0x07){
-+                      /*if((m88ds3103_readreg(state, 0x0d) & 0x07) == 0x07)*/
-+                              *status = FE_HAS_SIGNAL | FE_HAS_CARRIER 
-+                                      | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-+                      
-+              }
-+              break;
-+      case SYS_DVBS2:
-+              lock = m88ds3103_readreg(state, 0x0d);
-+              dprintk("%s: SYS_DVBS2 status=%x.\n", __func__, lock);
-+
-+              if ((lock & 0x8f) == 0x8f)
-+                      *status = FE_HAS_SIGNAL | FE_HAS_CARRIER 
-+                              | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-+                      
-+              break;
-+      default:
-+              break;
-+      }
-+
-+      return 0;
-+}
-+
-+static int m88ds3103_read_ber(struct dvb_frontend *fe, u32* ber)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      u8 tmp1, tmp2, tmp3;
-+      u32 ldpc_frame_cnt, pre_err_packags, code_rate_fac = 0;
-+
-+      dprintk("%s()\n", __func__);
-+
-+      switch (state->delivery_system) {
-+      case SYS_DVBS:
-+              m88ds3103_writereg(state, 0xf9, 0x04);
-+              tmp3 = m88ds3103_readreg(state, 0xf8);
-+              if ((tmp3&0x10) == 0){
-+                      tmp1 = m88ds3103_readreg(state, 0xf7);
-+                      tmp2 = m88ds3103_readreg(state, 0xf6);
-+                      tmp3 |= 0x10;
-+                      m88ds3103_writereg(state, 0xf8, tmp3);
-+                      state->preBer = (tmp1<<8) | tmp2;
-+              }
-+              break;
-+      case SYS_DVBS2:
-+              tmp1 = m88ds3103_readreg(state, 0x7e) & 0x0f;
-+              switch(tmp1){
-+              case 0: code_rate_fac = 16008 - 80; break;
-+              case 1: code_rate_fac = 21408 - 80; break;
-+              case 2: code_rate_fac = 25728 - 80; break;
-+              case 3: code_rate_fac = 32208 - 80; break;
-+              case 4: code_rate_fac = 38688 - 80; break;
-+              case 5: code_rate_fac = 43040 - 80; break;
-+              case 6: code_rate_fac = 48408 - 80; break;
-+              case 7: code_rate_fac = 51648 - 80; break;
-+              case 8: code_rate_fac = 53840 - 80; break;
-+              case 9: code_rate_fac = 57472 - 80; break;
-+              case 10: code_rate_fac = 58192 - 80; break;
-+              }
-+              
-+              tmp1 = m88ds3103_readreg(state, 0xd7) & 0xff;
-+              tmp2 = m88ds3103_readreg(state, 0xd6) & 0xff;
-+              tmp3 = m88ds3103_readreg(state, 0xd5) & 0xff;           
-+              ldpc_frame_cnt = (tmp1 << 16) | (tmp2 << 8) | tmp3;
-+
-+              tmp1 = m88ds3103_readreg(state, 0xf8) & 0xff;
-+              tmp2 = m88ds3103_readreg(state, 0xf7) & 0xff;
-+              pre_err_packags = tmp1<<8 | tmp2;
-+              
-+              if (ldpc_frame_cnt > 1000){
-+                      m88ds3103_writereg(state, 0xd1, 0x01);
-+                      m88ds3103_writereg(state, 0xf9, 0x01);
-+                      m88ds3103_writereg(state, 0xf9, 0x00);
-+                      m88ds3103_writereg(state, 0xd1, 0x00);
-+                      state->preBer = pre_err_packags;
-+              }                               
-+              break;
-+      default:
-+              break;
-+      }
-+      *ber = state->preBer;
-+      
-+      return 0;
-+}
-+
-+static int m88ds3103_read_signal_strength(struct dvb_frontend *fe,
-+                                              u16 *signal_strength)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      u16 gain;
-+      u8 gain1, gain2, gain3 = 0;
-+
-+      dprintk("%s()\n", __func__);
-+
-+      gain1 = m88ds3103_tuner_readreg(state, 0x3d) & 0x1f;
-+      dprintk("%s: gain1 = 0x%02x \n", __func__, gain1);
-+      
-+      if (gain1 > 15) gain1 = 15;
-+      gain2 = m88ds3103_tuner_readreg(state, 0x21) & 0x1f;
-+      dprintk("%s: gain2 = 0x%02x \n", __func__, gain2);
-+      
-+      if(state->tuner_id == TS2022_ID){
-+              gain3 = (m88ds3103_tuner_readreg(state, 0x66)>>3) & 0x07;
-+              dprintk("%s: gain3 = 0x%02x \n", __func__, gain3);
-+              
-+              if (gain2 > 16) gain2 = 16;
-+              if (gain2 < 2) gain2 = 2;                       
-+              if (gain3 > 6) gain3 = 6;
-+      }else{
-+              if (gain2 > 13) gain2 = 13;
-+              gain3 = 0;
-+      }
-+
-+      gain = gain1*23 + gain2*35 + gain3*29;
-+      *signal_strength = 60000 - gain*55;
-+
-+      return 0;
-+}
-+
-+
-+static int m88ds3103_read_snr(struct dvb_frontend *fe, u16 *p_snr)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      u8 val, npow1, npow2, spow1, cnt;
-+      u16 tmp, snr;
-+      u32 npow, spow, snr_total;      
-+      static const u16 mes_log10[] ={
-+              0,      3010,   4771,   6021,   6990,   7781,   8451,   9031,   9542,   10000,
-+              10414,  10792,  11139,  11461,  11761,  12041,  12304,  12553,  12788,  13010,
-+              13222,  13424,  13617,  13802,  13979,  14150,  14314,  14472,  14624,  14771,
-+              14914,  15052,  15185,  15315,  15441,  15563,  15682,  15798,  15911,  16021,
-+              16128,  16232,  16335,  16435,  16532,  16628,  16721,  16812,  16902,  16990,
-+              17076,  17160,  17243,  17324,  17404,  17482,  17559,  17634,  17709,  17782,
-+              17853,  17924,  17993,  18062,  18129,  18195,  18261,  18325,  18388,  18451,
-+              18513,  18573,  18633,  18692,  18751,  18808,  18865,  18921,  18976,  19031
-+      };
-+      static const u16 mes_loge[] ={
-+              0,      6931,   10986,  13863,  16094,  17918,  19459,  20794,  21972,  23026,
-+              23979,  24849,  25649,  26391,  27081,  27726,  28332,  28904,  29444,  29957,
-+              30445,  30910,  31355,  31781,  32189,  32581,  32958,  33322,  33673,  34012,
-+              34340,  34657,
-+      };
-+
-+      dprintk("%s()\n", __func__);
-+
-+      snr = 0;
-+      
-+      switch (state->delivery_system){
-+      case SYS_DVBS:
-+              cnt = 10; snr_total = 0;
-+              while(cnt > 0){
-+                      val = m88ds3103_readreg(state, 0xff);
-+                      snr_total += val;
-+                      cnt--;
-+              }
-+              tmp = (u16)(snr_total/80);
-+              if(tmp > 0){
-+                      if (tmp > 32) tmp = 32;
-+                      snr = (mes_loge[tmp - 1] * 100) / 45;
-+              }else{
-+                      snr = 0;
-+              }
-+              break;
-+      case SYS_DVBS2:
-+              cnt  = 10; npow = 0; spow = 0;
-+              while(cnt >0){
-+                      npow1 = m88ds3103_readreg(state, 0x8c) & 0xff;
-+                      npow2 = m88ds3103_readreg(state, 0x8d) & 0xff;
-+                      npow += (((npow1 & 0x3f) + (u16)(npow2 << 6)) >> 2);
-+
-+                      spow1 = m88ds3103_readreg(state, 0x8e) & 0xff;
-+                      spow += ((spow1 * spow1) >> 1);
-+                      cnt--;
-+              }
-+              npow /= 10; spow /= 10;
-+              if(spow == 0){
-+                      snr = 0;
-+              }else if(npow == 0){
-+                      snr = 19;
-+              }else{
-+                      if(spow > npow){
-+                              tmp = (u16)(spow / npow);
-+                              if (tmp > 80) tmp = 80;
-+                              snr = mes_log10[tmp - 1]*3;
-+                      }else{
-+                              tmp = (u16)(npow / spow);
-+                              if (tmp > 80) tmp = 80;
-+                              snr = -(mes_log10[tmp - 1] / 1000);
-+                      }
-+              }                       
-+              break;
-+      default:
-+              break;
-+      }
-+      *p_snr = snr;
-+
-+      return 0;
-+}
-+
-+
-+static int m88ds3103_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      u8 tmp1, tmp2, tmp3, data;
-+
-+      dprintk("%s()\n", __func__);
-+
-+      switch (state->delivery_system) {
-+      case SYS_DVBS:
-+              data = m88ds3103_readreg(state, 0xf8);
-+              data |= 0x40;
-+              m88ds3103_writereg(state, 0xf8, data);          
-+              tmp1 = m88ds3103_readreg(state, 0xf5);
-+              tmp2 = m88ds3103_readreg(state, 0xf4);
-+              *ucblocks = (tmp1 <<8) | tmp2;          
-+              data &= ~0x20;
-+              m88ds3103_writereg(state, 0xf8, data);
-+              data |= 0x20;
-+              m88ds3103_writereg(state, 0xf8, data);
-+              data &= ~0x40;
-+              m88ds3103_writereg(state, 0xf8, data);
-+              break;
-+      case SYS_DVBS2:
-+              tmp1 = m88ds3103_readreg(state, 0xda);
-+              tmp2 = m88ds3103_readreg(state, 0xd9);
-+              tmp3 = m88ds3103_readreg(state, 0xd8);
-+              *ucblocks = (tmp1 <<16)|(tmp2 <<8)|tmp3;
-+              data = m88ds3103_readreg(state, 0xd1);
-+              data |= 0x01;
-+              m88ds3103_writereg(state, 0xd1, data);
-+              data &= ~0x01;
-+              m88ds3103_writereg(state, 0xd1, data);
-+              break;
-+      default:
-+              break;
-+      }
-+      return 0;
-+}
-+
-+static int m88ds3103_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      u8 data_a1, data_a2;
-+
-+      dprintk("%s(%d)\n", __func__, tone);
-+      if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
-+              printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
-+              return -EINVAL;
-+      }
-+
-+      data_a1 = m88ds3103_readreg(state, 0xa1);
-+      data_a2 = m88ds3103_readreg(state, 0xa2);
-+      if(state->demod_id == DS3103_ID)
-+              data_a2 &= 0xdf; /* Normal mode */
-+      switch (tone) {
-+      case SEC_TONE_ON:
-+              dprintk("%s: SEC_TONE_ON\n", __func__);
-+              data_a1 |= 0x04;
-+              data_a1 &= ~0x03;
-+              data_a1 &= ~0x40;
-+              data_a2 &= ~0xc0;
-+              break;
-+      case SEC_TONE_OFF:
-+              dprintk("%s: SEC_TONE_OFF\n", __func__);
-+              data_a2 &= ~0xc0;
-+              data_a2 |= 0x80;
-+              break;
-+      }
-+      m88ds3103_writereg(state, 0xa2, data_a2);
-+      m88ds3103_writereg(state, 0xa1, data_a1);
-+      return 0;
-+}
-+
-+static int m88ds3103_send_diseqc_msg(struct dvb_frontend *fe,
-+                              struct dvb_diseqc_master_cmd *d)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      int i, ret = 0;
-+      u8 tmp, time_out;
-+
-+      /* Dump DiSEqC message */
-+      if (debug) {
-+              printk(KERN_INFO "m88ds3103: %s(", __func__);
-+              for (i = 0 ; i < d->msg_len ;) {
-+                      printk(KERN_INFO "0x%02x", d->msg[i]);
-+                      if (++i < d->msg_len)
-+                              printk(KERN_INFO ", ");
-+              }
-+      }
-+
-+      tmp = m88ds3103_readreg(state, 0xa2);
-+      tmp &= ~0xc0;
-+      if(state->demod_id == DS3103_ID)
-+              tmp &= ~0x20;
-+      m88ds3103_writereg(state, 0xa2, tmp);
-+      
-+      for (i = 0; i < d->msg_len; i ++)
-+              m88ds3103_writereg(state, (0xa3+i), d->msg[i]);
-+
-+      tmp = m88ds3103_readreg(state, 0xa1);   
-+      tmp &= ~0x38;
-+      tmp &= ~0x40;
-+      tmp |= ((d->msg_len-1) << 3) | 0x07;
-+      tmp &= ~0x80;
-+      m88ds3103_writereg(state, 0xa1, tmp);
-+      /*      1.5 * 9 * 8     = 108ms */
-+      time_out = 150;
-+      while (time_out > 0){
-+              msleep(10);
-+              time_out -= 10;
-+              tmp = m88ds3103_readreg(state, 0xa1);           
-+              if ((tmp & 0x40) == 0)
-+                      break;
-+      }
-+      if (time_out == 0){
-+              tmp = m88ds3103_readreg(state, 0xa1);
-+              tmp &= ~0x80;
-+              tmp |= 0x40;
-+              m88ds3103_writereg(state, 0xa1, tmp);
-+              ret = 1;
-+      }
-+      tmp = m88ds3103_readreg(state, 0xa2);
-+      tmp &= ~0xc0;
-+      tmp |= 0x80;
-+      m88ds3103_writereg(state, 0xa2, tmp);   
-+      return ret;
-+}
-+
-+
-+static int m88ds3103_diseqc_send_burst(struct dvb_frontend *fe,
-+                                      fe_sec_mini_cmd_t burst)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      u8      val, time_out;
-+      
-+      dprintk("%s()\n", __func__);
-+
-+      val = m88ds3103_readreg(state, 0xa2);
-+      val &= ~0xc0;
-+      if(state->demod_id == DS3103_ID)
-+              val &= 0xdf; /* Normal mode */
-+      m88ds3103_writereg(state, 0xa2, val);
-+      /* DiSEqC burst */
-+      if (burst == SEC_MINI_B)
-+              m88ds3103_writereg(state, 0xa1, 0x01);
-+      else
-+              m88ds3103_writereg(state, 0xa1, 0x02);
-+
-+      msleep(13);
-+
-+      time_out = 5;
-+      do{
-+              val = m88ds3103_readreg(state, 0xa1);
-+              if ((val & 0x40) == 0)
-+                      break;
-+              msleep(1);
-+              time_out --;
-+      } while (time_out > 0);
-+
-+      val = m88ds3103_readreg(state, 0xa2);
-+      val &= ~0xc0;
-+      val |= 0x80;
-+      m88ds3103_writereg(state, 0xa2, val);
-+      
-+      return 0;
-+}
-+
-+static void m88ds3103_release(struct dvb_frontend *fe)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+
-+      dprintk("%s\n", __func__);
-+      kfree(state);
-+}
-+
-+static int m88ds3103_check_id(struct m88ds3103_state *state)
-+{
-+      int val_00, val_01;
-+      
-+      /*check demod id*/
-+      val_01 = m88ds3103_readreg(state, 0x01);
-+      printk(KERN_INFO "DS3000 chip version: %x attached.\n", val_01);
-+                      
-+      if(val_01 == 0xD0)
-+              state->demod_id = DS3103_ID;
-+      else if(val_01 == 0xC0)
-+              state->demod_id = DS3000_ID;
-+      else
-+              state->demod_id = UNKNOW_ID;
-+              
-+      /*check tuner id*/
-+      val_00 = m88ds3103_tuner_readreg(state, 0x00);
-+      printk(KERN_INFO "TS202x chip version[1]: %x attached.\n", val_00);
-+      val_00 &= 0x03;
-+      if(val_00 == 0)
-+      {
-+              m88ds3103_tuner_writereg(state, 0x00, 0x01);
-+              msleep(3);              
-+      }
-+      m88ds3103_tuner_writereg(state, 0x00, 0x03);
-+      msleep(5);
-+      
-+      val_00 = m88ds3103_tuner_readreg(state, 0x00);
-+      printk(KERN_INFO "TS202x chip version[2]: %x attached.\n", val_00);
-+      val_00 &= 0xff;
-+      if((val_00 == 0x01) || (val_00 == 0x41) || (val_00 == 0x81))
-+              state->tuner_id = TS2020_ID;
-+      else if(((val_00 & 0xc0)== 0xc0) || (val_00 == 0x83))
-+              state->tuner_id = TS2022_ID;
-+      else
-+              state->tuner_id = UNKNOW_ID;
-+                      
-+      return state->demod_id; 
-+}
-+
-+static struct dvb_frontend_ops m88ds3103_ops;
-+static int m88ds3103_initilaze(struct dvb_frontend *fe);
-+
-+struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *config,
-+                                  struct i2c_adapter *i2c)
-+{
-+      struct m88ds3103_state *state = NULL;
-+
-+      dprintk("%s\n", __func__);
-+
-+      /* allocate memory for the internal state */
-+      state = kzalloc(sizeof(struct m88ds3103_state), GFP_KERNEL);
-+      if (state == NULL) {
-+              printk(KERN_ERR "Unable to kmalloc\n");
-+              goto error2;
-+      }
-+
-+      state->config = config;
-+      state->i2c = i2c;
-+      state->preBer = 0xffff;
-+      state->delivery_system = SYS_DVBS; /*Default to DVB-S.*/
-+      
-+      /* check demod id */
-+      if(m88ds3103_check_id(state) == UNKNOW_ID){
-+              printk(KERN_ERR "Unable to find Montage chip\n");
-+              goto error3;
-+      }
-+
-+      memcpy(&state->frontend.ops, &m88ds3103_ops,
-+                      sizeof(struct dvb_frontend_ops));
-+      state->frontend.demodulator_priv = state;
-+      
-+      m88ds3103_initilaze(&state->frontend);
-+      
-+      return &state->frontend;
-+
-+error3:
-+      kfree(state);
-+error2:
-+      return NULL;
-+}
-+EXPORT_SYMBOL(m88ds3103_attach);
-+
-+static int m88ds3103_set_carrier_offset(struct dvb_frontend *fe,
-+                                      s32 carrier_offset_khz)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      s32 tmp;
-+
-+      tmp = carrier_offset_khz;
-+      tmp *= 65536;
-+      
-+      tmp = (2*tmp + MT_FE_MCLK_KHZ) / (2*MT_FE_MCLK_KHZ);
-+
-+      if (tmp < 0)
-+              tmp += 65536;
-+
-+      m88ds3103_writereg(state, 0x5f, tmp >> 8);
-+      m88ds3103_writereg(state, 0x5e, tmp & 0xff);
-+
-+      return 0;
-+}
-+
-+static int m88ds3103_set_symrate(struct dvb_frontend *fe)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-+      u16 value;
-+      
-+      value = (((c->symbol_rate / 1000) << 15) + (MT_FE_MCLK_KHZ / 4)) / (MT_FE_MCLK_KHZ / 2);
-+      m88ds3103_writereg(state, 0x61, value & 0x00ff);
-+      m88ds3103_writereg(state, 0x62, (value & 0xff00) >> 8);
-+
-+      return 0;
-+}
-+
-+static int m88ds3103_set_CCI(struct dvb_frontend *fe)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      u8 tmp;
-+
-+      tmp = m88ds3103_readreg(state, 0x56);
-+      tmp &= ~0x01;
-+      m88ds3103_writereg(state, 0x56, tmp);
-+
-+      tmp = m88ds3103_readreg(state, 0x76);
-+      tmp &= ~0x80;
-+      m88ds3103_writereg(state, 0x76, tmp);
-+
-+      return 0;
-+}
-+
-+static int m88ds3103_init_reg(struct m88ds3103_state *state, const u8 *p_reg_tab, u32 size)
-+{
-+      u32 i;
-+      
-+      for(i = 0; i < size; i+=2)
-+              m88ds3103_writereg(state, p_reg_tab[i], p_reg_tab[i+1]);
-+              
-+      return 0;
-+}
-+
-+static int m88ds3103_get_locked_sym_rate(struct m88ds3103_state *state, u32 *sym_rate_KSs)
-+{
-+      u16     tmp;
-+      u32     sym_rate_tmp;
-+      u8      val_0x6d, val_0x6e;
-+
-+      val_0x6d = m88ds3103_readreg(state, 0x6d);
-+      val_0x6e = m88ds3103_readreg(state, 0x6e);
-+
-+      tmp = (u16)((val_0x6e<<8) | val_0x6d);
-+
-+      sym_rate_tmp = (u32)(tmp * MT_FE_MCLK_KHZ);
-+      sym_rate_tmp = (u32)(sym_rate_tmp / (1<<16));
-+      *sym_rate_KSs = sym_rate_tmp;
-+
-+      return 0;
-+}
-+
-+static int m88ds3103_get_channel_info(struct m88ds3103_state *state, u8 *p_mode, u8 *p_coderate)
-+{
-+      u8      tmp, val_0x7E;
-+
-+      if(state->delivery_system == SYS_DVBS2){
-+              val_0x7E = m88ds3103_readreg(state, 0x7e);
-+              tmp = (u8)((val_0x7E&0xC0) >> 6);
-+              *p_mode = tmp;
-+              tmp = (u8)(val_0x7E & 0x0f);
-+              *p_coderate = tmp;
-+      } else {
-+              *p_mode = 0;
-+              tmp = m88ds3103_readreg(state, 0xe6);           
-+              tmp = (u8)(tmp >> 5);
-+              *p_coderate = tmp;
-+      }
-+      
-+      return 0;
-+}
-+
-+static int m88ds3103_set_clock_ratio(struct m88ds3103_state *state)
-+{
-+      u8      val, mod_fac, tmp1, tmp2;
-+      u32     input_datarate, locked_sym_rate_KSs;
-+      u32 MClk_KHz = 96000;
-+      u8 mod_mode, code_rate, divid_ratio = 0;
-+
-+      locked_sym_rate_KSs = 0;
-+      m88ds3103_get_locked_sym_rate(state, &locked_sym_rate_KSs);
-+      if(locked_sym_rate_KSs == 0)
-+              return 0;
-+
-+      m88ds3103_get_channel_info(state, &mod_mode, &code_rate);
-+
-+      if (state->delivery_system == SYS_DVBS2)
-+      {
-+              switch(mod_mode) {
-+                      case 1: mod_fac = 3; break;
-+                      case 2: mod_fac = 4; break;
-+                      case 3: mod_fac = 5; break;
-+                      default: mod_fac = 2; break;
-+              }
-+
-+              switch(code_rate) {
-+                      case 0: input_datarate = locked_sym_rate_KSs*mod_fac/8/4; break;
-+                      case 1: input_datarate = locked_sym_rate_KSs*mod_fac/8/3;       break;
-+                      case 2: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/5;     break;
-+                      case 3: input_datarate = locked_sym_rate_KSs*mod_fac/8/2;       break;
-+                      case 4: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/5;     break;
-+                      case 5: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3;     break;
-+                      case 6: input_datarate = locked_sym_rate_KSs*mod_fac*3/8/4;     break;
-+                      case 7: input_datarate = locked_sym_rate_KSs*mod_fac*4/8/5;     break;
-+                      case 8: input_datarate = locked_sym_rate_KSs*mod_fac*5/8/6;     break;
-+                      case 9: input_datarate = locked_sym_rate_KSs*mod_fac*8/8/9;     break;
-+                      case 10: input_datarate = locked_sym_rate_KSs*mod_fac*9/8/10; break;
-+                      default: input_datarate = locked_sym_rate_KSs*mod_fac*2/8/3; break;
-+              }
-+
-+              if(state->demod_id == DS3000_ID)
-+                      input_datarate = input_datarate * 115 / 100;
-+
-+              if(input_datarate < 4800)  {tmp1 = 15;tmp2 = 15;} //4.8MHz         TS clock
-+              else if(input_datarate < 4966)  {tmp1 = 14;tmp2 = 15;} //4.966MHz  TS clock
-+              else if(input_datarate < 5143)  {tmp1 = 14;tmp2 = 14;} //5.143MHz  TS clock
-+              else if(input_datarate < 5333)  {tmp1 = 13;tmp2 = 14;} //5.333MHz  TS clock
-+              else if(input_datarate < 5538)  {tmp1 = 13;tmp2 = 13;} //5.538MHz  TS clock
-+              else if(input_datarate < 5760)  {tmp1 = 12;tmp2 = 13;} //5.76MHz   TS clock       allan 0809
-+              else if(input_datarate < 6000)  {tmp1 = 12;tmp2 = 12;} //6MHz      TS clock
-+              else if(input_datarate < 6260)  {tmp1 = 11;tmp2 = 12;} //6.26MHz   TS clock
-+              else if(input_datarate < 6545)  {tmp1 = 11;tmp2 = 11;} //6.545MHz  TS clock
-+              else if(input_datarate < 6857)  {tmp1 = 10;tmp2 = 11;} //6.857MHz  TS clock
-+              else if(input_datarate < 7200)  {tmp1 = 10;tmp2 = 10;} //7.2MHz    TS clock
-+              else if(input_datarate < 7578)  {tmp1 = 9;tmp2 = 10;}  //7.578MHz  TS clock
-+              else if(input_datarate < 8000)  {tmp1 = 9;tmp2 = 9;}   //8MHz      TS clock
-+              else if(input_datarate < 8470)  {tmp1 = 8;tmp2 = 9;}   //8.47MHz   TS clock
-+              else if(input_datarate < 9000)  {tmp1 = 8;tmp2 = 8;}   //9MHz      TS clock
-+              else if(input_datarate < 9600)  {tmp1 = 7;tmp2 = 8;}   //9.6MHz    TS clock
-+              else if(input_datarate < 10285) {tmp1 = 7;tmp2 = 7;}   //10.285MHz TS clock
-+              else if(input_datarate < 12000) {tmp1 = 6;tmp2 = 6;}   //12MHz     TS clock
-+              else if(input_datarate < 14400) {tmp1 = 5;tmp2 = 5;}   //14.4MHz   TS clock
-+              else if(input_datarate < 18000) {tmp1 = 4;tmp2 = 4;}   //18MHz     TS clock
-+              else                                                    {tmp1 = 3;tmp2 = 3;}   //24MHz     TS clock
-+
-+              if(state->demod_id == DS3000_ID) {
-+                      val = (u8)((tmp1<<4) + tmp2);
-+                      m88ds3103_writereg(state, 0xfe, val);
-+              } else {
-+                      tmp1 = m88ds3103_readreg(state, 0x22);
-+                      tmp2 = m88ds3103_readreg(state, 0x24);
-+
-+                      tmp1 >>= 6;
-+                      tmp1 &= 0x03;
-+                      tmp2 >>= 6;
-+                      tmp2 &= 0x03;
-+
-+                      if((tmp1 == 0x00) && (tmp2 == 0x01))
-+                              MClk_KHz = 144000;
-+                      else if((tmp1 == 0x00) && (tmp2 == 0x03))
-+                              MClk_KHz = 72000;
-+                      else if((tmp1 == 0x01) && (tmp2 == 0x01))
-+                              MClk_KHz = 115200;
-+                      else if((tmp1 == 0x02) && (tmp2 == 0x01))
-+                              MClk_KHz = 96000;
-+                      else if((tmp1 == 0x03) && (tmp2 == 0x00))
-+                              MClk_KHz = 192000;
-+                      else
-+                              return 0;
-+
-+                      if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/
-+                              input_datarate = 5200;
-+                              
-+                      if(input_datarate != 0)
-+                              divid_ratio = (u8)(MClk_KHz / input_datarate);
-+                      else
-+                              divid_ratio = 0xFF;
-+
-+                      if(divid_ratio > 128)
-+                              divid_ratio = 128;
-+
-+                      if(divid_ratio < 2)
-+                              divid_ratio = 2;
-+
-+                      tmp1 = (u8)(divid_ratio / 2);
-+                      tmp2 = (u8)(divid_ratio / 2);
-+
-+                      if((divid_ratio % 2) != 0)
-+                              tmp2 += 1;
-+
-+                      tmp1 -= 1;
-+                      tmp2 -= 1;
-+
-+                      tmp1 &= 0x3f;
-+                      tmp2 &= 0x3f;
-+
-+                      val = m88ds3103_readreg(state, 0xfe);
-+                      val &= 0xF0;
-+                      val |= (tmp2 >> 2) & 0x0f;
-+                      m88ds3103_writereg(state, 0xfe, val);
-+
-+                      val = (u8)((tmp2 & 0x03) << 6); 
-+                      val |= tmp1;
-+                      m88ds3103_writereg(state, 0xea, val);
-+              }
-+      } else {
-+              mod_fac = 2;
-+
-+              switch(code_rate) {
-+                      case 4: input_datarate = locked_sym_rate_KSs*mod_fac/2/8;       break;
-+                      case 3: input_datarate = locked_sym_rate_KSs*mod_fac*2/3/8;     break;
-+                      case 2: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8;     break;
-+                      case 1: input_datarate = locked_sym_rate_KSs*mod_fac*5/6/8;     break;
-+                      case 0: input_datarate = locked_sym_rate_KSs*mod_fac*7/8/8;     break;
-+                      default: input_datarate = locked_sym_rate_KSs*mod_fac*3/4/8;    break;
-+              }
-+
-+              if(state->demod_id == DS3000_ID)
-+                      input_datarate = input_datarate * 115 / 100;
-+
-+              if(input_datarate < 6857)               {tmp1 = 7;tmp2 = 7;} //6.857MHz     TS clock
-+              else if(input_datarate < 7384)  {tmp1 = 6;tmp2 = 7;} //7.384MHz     TS clock
-+              else if(input_datarate < 8000)  {tmp1 = 6;tmp2 = 6;} //8MHz             TS clock
-+              else if(input_datarate < 8727)  {tmp1 = 5;tmp2 = 6;} //8.727MHz         TS clock
-+              else if(input_datarate < 9600)  {tmp1 = 5;tmp2 = 5;} //9.6MHz           TS clock
-+              else if(input_datarate < 10666) {tmp1 = 4;tmp2 = 5;} //10.666MHz        TS clock
-+              else if(input_datarate < 12000) {tmp1 = 4;tmp2 = 4;} //12MHz            TS clock
-+              else if(input_datarate < 13714) {tmp1 = 3;tmp2 = 4;} //13.714MHz        TS clock
-+              else if(input_datarate < 16000) {tmp1 = 3;tmp2 = 3;} //16MHz            TS clock
-+              else if(input_datarate < 19200) {tmp1 = 2;tmp2 = 3;} //19.2MHz          TS clock
-+              else                                                    {tmp1 = 2;tmp2 = 2;} //24MHz            TS clock
-+
-+              if(state->demod_id == DS3000_ID) {
-+                      val = m88ds3103_readreg(state, 0xfe);
-+                      val &= 0xc0;
-+                      val |= ((u8)((tmp1<<3) + tmp2));
-+                      m88ds3103_writereg(state, 0xfe, val);
-+              } else {
-+                      if(input_datarate < 5200) /*Max. 2011-12-23 11:55*/
-+                              input_datarate = 5200;
-+                      
-+                      if(input_datarate != 0)
-+                              divid_ratio = (u8)(MClk_KHz / input_datarate);
-+                      else
-+                              divid_ratio = 0xFF;
-+
-+                      if(divid_ratio > 128)
-+                              divid_ratio = 128;
-+
-+                      if(divid_ratio < 2)
-+                              divid_ratio = 2;
-+
-+                      tmp1 = (u8)(divid_ratio / 2);
-+                      tmp2 = (u8)(divid_ratio / 2);
-+
-+                      if((divid_ratio % 2) != 0)
-+                              tmp2 += 1;
-+
-+                      tmp1 -= 1;
-+                      tmp2 -= 1;
-+
-+                      tmp1 &= 0x3f;
-+                      tmp2 &= 0x3f;
-+
-+                      val = m88ds3103_readreg(state, 0xfe);
-+                      val &= 0xF0;
-+                      val |= (tmp2 >> 2) & 0x0f;
-+                      m88ds3103_writereg(state, 0xfe, val);
-+                      
-+                      val = (u8)((tmp2 & 0x03) << 6);
-+                      val |= tmp1;
-+                      m88ds3103_writereg(state, 0xea, val);
-+              }
-+      }
-+      return 0;
-+}
-+
-+static int m88ds3103_demod_connect(struct dvb_frontend *fe, s32 carrier_offset_khz) 
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-+      u16 value;
-+      u8 val1,val2,data;
-+      
-+      dprintk("connect delivery system = %d\n", state->delivery_system);
-+      
-+      /* ds3000 global reset */
-+      m88ds3103_writereg(state, 0x07, 0x80);
-+      m88ds3103_writereg(state, 0x07, 0x00);
-+      /* ds3000 build-in uC reset */
-+      m88ds3103_writereg(state, 0xb2, 0x01);
-+      /* ds3000 software reset */
-+      m88ds3103_writereg(state, 0x00, 0x01);
-+
-+      switch (state->delivery_system) {
-+      case SYS_DVBS:
-+              /* initialise the demod in DVB-S mode */
-+              if(state->demod_id == DS3000_ID){
-+                      m88ds3103_init_reg(state, ds3000_dvbs_init_tab, sizeof(ds3000_dvbs_init_tab));
-+                      
-+                      value = m88ds3103_readreg(state, 0xfe);
-+                      value &= 0xc0;
-+                      value |= 0x1b;
-+                      m88ds3103_writereg(state, 0xfe, value);
-+                      
-+                      if(state->config->ci_mode)
-+                              val1 = 0x80;
-+                      else if(state->config->ts_mode)
-+                              val1 = 0x60;
-+                      else
-+                              val1 = 0x20;
-+                      m88ds3103_writereg(state, 0xfd, val1);
-+                      
-+              }else if(state->demod_id == DS3103_ID){
-+                      m88ds3103_init_reg(state, ds3103_dvbs_init_tab, sizeof(ds3103_dvbs_init_tab));
-+                      
-+                      /* set ts clock */
-+                      if(state->config->ci_mode == 2){
-+                              val1 = 6; val2 = 6;
-+                      }else if(state->config->ts_mode == 0)   {
-+                              val1 = 3; val2 = 3;
-+                      }else{
-+                              val1 = 0; val2 = 0;
-+                      }
-+                      val1 -= 1; val2 -= 1;
-+                      val1 &= 0x3f; val2 &= 0x3f;
-+                      data = m88ds3103_readreg(state, 0xfe);
-+                      data &= 0xf0;
-+                      data |= (val2 >> 2) & 0x0f;
-+                      m88ds3103_writereg(state, 0xfe, data);
-+                      data = (val2 & 0x03) << 6;
-+                      data |= val1;
-+                      m88ds3103_writereg(state, 0xea, data);
-+                      
-+                      m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
-+                      m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
-+                      
-+                      /* set master clock */
-+                      val1 = m88ds3103_readreg(state, 0x22);
-+                      val2 = m88ds3103_readreg(state, 0x24);
-+                      
-+                      val1 &= 0x3f;
-+                      val2 &= 0x3f;
-+                      val1 |= 0x80;
-+                      val2 |= 0x40;
-+
-+                      m88ds3103_writereg(state, 0x22, val1);
-+                      m88ds3103_writereg(state, 0x24, val2);  
-+                      
-+                      if(state->config->ci_mode)
-+                              val1 = 0x03;
-+                      else if(state->config->ts_mode)
-+                              val1 = 0x06;
-+                      else
-+                              val1 = 0x42;
-+                      m88ds3103_writereg(state, 0xfd, val1);          
-+              }
-+              break;
-+      case SYS_DVBS2:
-+              /* initialise the demod in DVB-S2 mode */
-+              if(state->demod_id == DS3000_ID){
-+                      m88ds3103_init_reg(state, ds3000_dvbs2_init_tab, sizeof(ds3000_dvbs2_init_tab));
-+              
-+                      if (c->symbol_rate >= 30000000)
-+                              m88ds3103_writereg(state, 0xfe, 0x54);
-+                      else
-+                              m88ds3103_writereg(state, 0xfe, 0x98);
-+                                                              
-+              }else if(state->demod_id == DS3103_ID){
-+                      m88ds3103_init_reg(state, ds3103_dvbs2_init_tab, sizeof(ds3103_dvbs2_init_tab));
-+
-+                      /* set ts clock */
-+                      if(state->config->ci_mode == 2){
-+                              val1 = 6; val2 = 6;
-+                      }else if(state->config->ts_mode == 0){
-+                              val1 = 5; val2 = 4;
-+                      }else{
-+                              val1 = 0; val2 = 0;
-+                      }
-+                      val1 -= 1; val2 -= 1;
-+                      val1 &= 0x3f; val2 &= 0x3f;
-+                      data = m88ds3103_readreg(state, 0xfe);
-+                      data &= 0xf0;
-+                      data |= (val2 >> 2) & 0x0f;
-+                      m88ds3103_writereg(state, 0xfe, data);
-+                      data = (val2 & 0x03) << 6;
-+                      data |= val1;
-+                      m88ds3103_writereg(state, 0xea, data);
-+                      
-+                      m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
-+                      m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));
-+                      
-+                      /* set master clock */
-+                      val1 = m88ds3103_readreg(state, 0x22);
-+                      val2 = m88ds3103_readreg(state, 0x24);
-+                      
-+                      val1 &= 0x3f;
-+                      val2 &= 0x3f;
-+                      if((state->config->ci_mode == 2) || (state->config->ts_mode == 1)){
-+                              val1 |= 0x80;
-+                              val2 |= 0x40;
-+                      }else{
-+                              if (c->symbol_rate >= 28000000){
-+                                      val1 |= 0xc0;
-+                              }else if (c->symbol_rate >= 18000000){
-+                                      val2 |= 0x40;
-+                              }else{
-+                                      val1 |= 0x80;
-+                                      val2 |= 0x40;
-+                              }                               
-+                      }
-+                      m88ds3103_writereg(state, 0x22, val1);
-+                      m88ds3103_writereg(state, 0x24, val2);                                  
-+              }
-+              
-+              if(state->config->ci_mode)
-+                      val1 = 0x03;
-+              else if(state->config->ts_mode)
-+                      val1 = 0x06;
-+              else
-+                      val1 = 0x42;
-+              m88ds3103_writereg(state, 0xfd, val1);
-+              
-+              break;
-+      default:
-+              return 1;
-+      }
-+      /* disable 27MHz clock output */
-+      m88ds3103_writereg(state, 0x29, 0x80);
-+      /* enable ac coupling */
-+      m88ds3103_writereg(state, 0x25, 0x8a);
-+
-+      if ((c->symbol_rate / 1000) <= 3000){
-+              m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 32 * 100 / 64 = 400*/
-+              m88ds3103_writereg(state, 0xc8, 0x20);
-+              m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/
-+              m88ds3103_writereg(state, 0xc7, 0x00);
-+      }else if((c->symbol_rate / 1000) <= 10000){
-+              m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 16 * 100 / 64 = 200*/
-+              m88ds3103_writereg(state, 0xc8, 0x10);
-+              m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/
-+              m88ds3103_writereg(state, 0xc7, 0x00);
-+      }else{
-+              m88ds3103_writereg(state, 0xc3, 0x08); /* 8 * 6 * 100 / 64 = 75*/
-+              m88ds3103_writereg(state, 0xc8, 0x06);
-+              m88ds3103_writereg(state, 0xc4, 0x08); /* 8 * 0 * 100 / 128 = 0*/
-+              m88ds3103_writereg(state, 0xc7, 0x00);
-+      }
-+
-+      m88ds3103_set_symrate(fe);
-+      
-+      m88ds3103_set_CCI(fe);
-+
-+      m88ds3103_set_carrier_offset(fe, carrier_offset_khz);
-+              
-+      /* ds3000 out of software reset */
-+      m88ds3103_writereg(state, 0x00, 0x00);
-+      /* start ds3000 build-in uC */
-+      m88ds3103_writereg(state, 0xb2, 0x00);  
-+      
-+      return 0;
-+}
-+
-+static int m88ds3103_set_frontend(struct dvb_frontend *fe)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-+
-+      int i;
-+      fe_status_t status;
-+      u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf, div4, capCode, changePLL;
-+      s32 offset_khz, lpf_offset_KHz;
-+      u16 value, ndiv, lpf_coeff;
-+      u32 f3db, gdiv28, realFreq;
-+      u8 RFgain;
-+
-+      dprintk("%s() ", __func__);
-+      dprintk("c frequency = %d\n", c->frequency);
-+      dprintk("symbol rate = %d\n", c->symbol_rate);
-+      dprintk("delivery system = %d\n", c->delivery_system);
-+      
-+      realFreq = c->frequency;
-+      lpf_offset_KHz = 0;
-+      if(c->symbol_rate < 5000000){
-+              lpf_offset_KHz = FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz;
-+              realFreq += FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz;
-+      }
-+      
-+      if (state->config->set_ts_params)
-+              state->config->set_ts_params(fe, 0);
-+
-+      div4 = 0;
-+      RFgain = 0;
-+      if(state->tuner_id == TS2022_ID){
-+              m88ds3103_tuner_writereg(state, 0x10, 0x0a);
-+              m88ds3103_tuner_writereg(state, 0x11, 0x40);
-+              if (realFreq < 1103000) {
-+                      m88ds3103_tuner_writereg(state, 0x10, 0x1b);
-+                      div4 = 1;
-+                      ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ;                              
-+              }else {
-+                      ndiv = (realFreq * (6 + 8) * 2)/MT_FE_CRYSTAL_KHZ;
-+              }
-+              ndiv = ndiv + ndiv%2;
-+              if(ndiv < 4095)
-+                      ndiv = ndiv - 1024;
-+              else if (ndiv < 6143)
-+                      ndiv = ndiv + 1024;
-+              else
-+                      ndiv = ndiv + 3072;     
-+              
-+              m88ds3103_tuner_writereg(state, 0x01, (ndiv & 0x3f00) >> 8);                                                                                    
-+      }else{
-+              m88ds3103_tuner_writereg(state, 0x10, 0x00);                    
-+              if (realFreq < 1146000){
-+                      m88ds3103_tuner_writereg(state, 0x10, 0x11);
-+                      div4 = 1;
-+                      ndiv = (realFreq * (6 + 8) * 4) / MT_FE_CRYSTAL_KHZ;
-+              }else{
-+                      m88ds3103_tuner_writereg(state, 0x10, 0x01);
-+                      ndiv = (realFreq * (6 + 8) * 2) / MT_FE_CRYSTAL_KHZ;
-+              }
-+              ndiv = ndiv + ndiv%2;
-+              ndiv = ndiv - 1024;
-+              m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8)&0x0f);
-+      }
-+      /* set pll */
-+      m88ds3103_tuner_writereg(state, 0x02, ndiv & 0x00ff);
-+      m88ds3103_tuner_writereg(state, 0x03, 0x06);
-+      m88ds3103_tuner_writereg(state, 0x51, 0x0f);
-+      m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x10);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x00);    
-+
-+      if(state->tuner_id == TS2022_ID){
-+              if(( realFreq >= 1650000 ) && (realFreq <= 1850000)){
-+                      msleep(5);
-+                      value = m88ds3103_tuner_readreg(state, 0x14);
-+                      value &= 0x7f;
-+                      if(value < 64){
-+                              m88ds3103_tuner_writereg(state, 0x10, 0x82);
-+                              m88ds3103_tuner_writereg(state, 0x11, 0x6f);
-+
-+                              m88ds3103_tuner_writereg(state, 0x51, 0x0f);
-+                              m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+                              m88ds3103_tuner_writereg(state, 0x50, 0x10);
-+                              m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+                      }
-+              }
-+              msleep(5);
-+              value = m88ds3103_tuner_readreg(state, 0x14);
-+              value &= 0x1f;
-+
-+              if(value > 19){
-+                      value = m88ds3103_tuner_readreg(state, 0x10);
-+                      value &= 0x1d;
-+                      m88ds3103_tuner_writereg(state, 0x10, value);
-+              }                               
-+      }else{
-+              msleep(5);
-+              value = m88ds3103_tuner_readreg(state, 0x66);
-+              changePLL = (((value & 0x80) >> 7) != div4);
-+
-+              if(changePLL){
-+                      m88ds3103_tuner_writereg(state, 0x10, 0x11);
-+                      div4 = 1;
-+                      ndiv = (realFreq * (6 + 8) * 4)/MT_FE_CRYSTAL_KHZ;
-+                      ndiv = ndiv + ndiv%2;
-+                      ndiv = ndiv - 1024;
-+                                      
-+                      m88ds3103_tuner_writereg(state, 0x01, (ndiv>>8) & 0x0f);
-+                      m88ds3103_tuner_writereg(state, 0x02, ndiv & 0xff);
-+                      
-+                      m88ds3103_tuner_writereg(state, 0x51, 0x0f);
-+                      m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+                      m88ds3103_tuner_writereg(state, 0x50, 0x10);
-+                      m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+              }               
-+      }
-+      /*set the RF gain*/
-+      if(state->tuner_id == TS2020_ID)
-+              m88ds3103_tuner_writereg(state, 0x60, 0x79);
-+                      
-+      m88ds3103_tuner_writereg(state, 0x51, 0x17);
-+      m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x08);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+      msleep(5);
-+
-+      if(state->tuner_id == TS2020_ID){
-+              RFgain = m88ds3103_tuner_readreg(state, 0x3d);
-+              RFgain &= 0x0f;
-+              if(RFgain < 15){
-+                      if(RFgain < 4) 
-+                              RFgain = 0;
-+                      else
-+                              RFgain = RFgain -3;
-+                      value = ((RFgain << 3) | 0x01) & 0x79;
-+                      m88ds3103_tuner_writereg(state, 0x60, value);
-+                      m88ds3103_tuner_writereg(state, 0x51, 0x17);
-+                      m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+                      m88ds3103_tuner_writereg(state, 0x50, 0x08);
-+                      m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+              }
-+      }
-+      
-+      /* set the LPF */
-+      if(state->tuner_id == TS2022_ID){
-+              m88ds3103_tuner_writereg(state, 0x25, 0x00);
-+              m88ds3103_tuner_writereg(state, 0x27, 0x70);
-+              m88ds3103_tuner_writereg(state, 0x41, 0x09);
-+              m88ds3103_tuner_writereg(state, 0x08, 0x0b);
-+      }
-+
-+      f3db = ((c->symbol_rate / 1000) *135) / 200 + 2000;
-+      f3db += lpf_offset_KHz;
-+      if (f3db < 7000)
-+              f3db = 7000;
-+      if (f3db > 40000)
-+              f3db = 40000;
-+                      
-+      gdiv28 = (MT_FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000;
-+      m88ds3103_tuner_writereg(state, 0x04, gdiv28 & 0xff);
-+      m88ds3103_tuner_writereg(state, 0x51, 0x1b);
-+      m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x04);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+      msleep(5);
-+
-+      value = m88ds3103_tuner_readreg(state, 0x26);
-+      capCode = value & 0x3f;
-+      if(state->tuner_id == TS2022_ID){
-+              m88ds3103_tuner_writereg(state, 0x41, 0x0d);
-+
-+              m88ds3103_tuner_writereg(state, 0x51, 0x1b);
-+              m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+              m88ds3103_tuner_writereg(state, 0x50, 0x04);
-+              m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+
-+              msleep(2);
-+
-+              value = m88ds3103_tuner_readreg(state, 0x26);
-+              value &= 0x3f;
-+              value = (capCode + value) / 2;          
-+      }
-+      else
-+              value = capCode;
-+              
-+      gdiv28 = gdiv28 * 207 / (value * 2 + 151);      
-+      mlpf_max = gdiv28 * 135 / 100;
-+      mlpf_min = gdiv28 * 78 / 100;
-+      if (mlpf_max > 63)
-+              mlpf_max = 63;
-+
-+      if(state->tuner_id == TS2022_ID)
-+              lpf_coeff = 3200;
-+      else
-+              lpf_coeff = 2766;
-+              
-+      nlpf = (f3db * gdiv28 * 2 / lpf_coeff / (MT_FE_CRYSTAL_KHZ / 1000)  + 1) / 2 ;  
-+      if (nlpf > 23) nlpf = 23;
-+      if (nlpf < 1) nlpf = 1;
-+
-+      lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3db + 1) / 2;
-+
-+      if (lpf_mxdiv < mlpf_min){
-+              nlpf++;
-+              lpf_mxdiv = (nlpf * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2  / f3db + 1) / 2;
-+      }
-+
-+      if (lpf_mxdiv > mlpf_max)
-+              lpf_mxdiv = mlpf_max;
-+
-+      m88ds3103_tuner_writereg(state, 0x04, lpf_mxdiv);
-+      m88ds3103_tuner_writereg(state, 0x06, nlpf);
-+      m88ds3103_tuner_writereg(state, 0x51, 0x1b);
-+      m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x04);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+      msleep(5);
-+      
-+      if(state->tuner_id == TS2022_ID){
-+              msleep(2);
-+              value = m88ds3103_tuner_readreg(state, 0x26);
-+              capCode = value & 0x3f;
-+
-+              m88ds3103_tuner_writereg(state, 0x41, 0x09);
-+
-+              m88ds3103_tuner_writereg(state, 0x51, 0x1b);
-+              m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+              m88ds3103_tuner_writereg(state, 0x50, 0x04);
-+              m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+
-+              msleep(2);
-+              value = m88ds3103_tuner_readreg(state, 0x26);
-+              value &= 0x3f;
-+              value = (capCode + value) / 2;
-+
-+              value = value | 0x80;
-+              m88ds3103_tuner_writereg(state, 0x25, value);
-+              m88ds3103_tuner_writereg(state, 0x27, 0x30);
-+
-+              m88ds3103_tuner_writereg(state, 0x08, 0x09);            
-+      }
-+
-+      /* Set the BB gain */
-+      m88ds3103_tuner_writereg(state, 0x51, 0x1e);
-+      m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x01);
-+      m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+      if(state->tuner_id == TS2020_ID){
-+              if(RFgain == 15){
-+                      msleep(40);
-+                      value = m88ds3103_tuner_readreg(state, 0x21);
-+                      value &= 0x0f;
-+                      if(value < 3){
-+                              m88ds3103_tuner_writereg(state, 0x60, 0x61);
-+                              m88ds3103_tuner_writereg(state, 0x51, 0x17);
-+                              m88ds3103_tuner_writereg(state, 0x51, 0x1f);
-+                              m88ds3103_tuner_writereg(state, 0x50, 0x08);
-+                              m88ds3103_tuner_writereg(state, 0x50, 0x00);
-+                      }                       
-+              }
-+      }
-+      msleep(60);
-+      
-+      offset_khz = (ndiv - ndiv % 2 + 1024) * MT_FE_CRYSTAL_KHZ
-+              / (6 + 8) / (div4 + 1) / 2 - realFreq;
-+
-+      m88ds3103_demod_connect(fe, offset_khz+lpf_offset_KHz);
-+
-+      for (i = 0; i < 30 ; i++) {
-+              m88ds3103_read_status(fe, &status);
-+              if (status & FE_HAS_LOCK){
-+                      break;
-+                }
-+              msleep(20);
-+      }
-+      
-+      if((status & FE_HAS_LOCK) == 0){
-+              state->delivery_system = (state->delivery_system == SYS_DVBS) ? SYS_DVBS2 : SYS_DVBS;
-+              m88ds3103_demod_connect(fe, offset_khz);
-+      
-+              for (i = 0; i < 30 ; i++) {
-+                      m88ds3103_read_status(fe, &status);
-+                      if (status & FE_HAS_LOCK){
-+                              break;
-+                      }
-+                      msleep(20);
-+              }
-+      }
-+      
-+      if (status & FE_HAS_LOCK){
-+              if(state->config->ci_mode == 2)
-+                      m88ds3103_set_clock_ratio(state);
-+              if(state->config->start_ctrl){
-+                      if(state->first_lock == 0){
-+                              state->config->start_ctrl(fe);
-+                              state->first_lock = 1;  
-+                      }
-+              }               
-+      }
-+              
-+      return 0;
-+}
-+
-+static int m88ds3103_tune(struct dvb_frontend *fe,
-+                      bool re_tune,
-+                      unsigned int mode_flags,
-+                      unsigned int *delay,
-+                      fe_status_t *status)
-+{     
-+      *delay = HZ / 5;
-+      
-+      dprintk("%s() ", __func__);
-+      dprintk("re_tune = %d\n", re_tune);
-+      
-+      if (re_tune) {
-+              int ret = m88ds3103_set_frontend(fe);
-+              if (ret)
-+                      return ret;
-+      }
-+      
-+      return m88ds3103_read_status(fe, status);
-+}
-+
-+static enum dvbfe_algo m88ds3103_get_algo(struct dvb_frontend *fe)
-+{
-+      return DVBFE_ALGO_HW;
-+}
-+ 
-+ /*
-+ * Power config will reset and load initial firmware if required
-+ */
-+static int m88ds3103_initilaze(struct dvb_frontend *fe)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      int ret;
-+
-+      dprintk("%s()\n", __func__);
-+      /* hard reset */
-+      m88ds3103_writereg(state, 0x07, 0x80);
-+      m88ds3103_writereg(state, 0x07, 0x00);
-+      msleep(1);
-+      
-+      m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08));
-+      msleep(1);
-+
-+      if(state->tuner_id == TS2020_ID){
-+              /* TS2020 init */
-+              m88ds3103_tuner_writereg(state, 0x42, 0x73);
-+              msleep(2);
-+              m88ds3103_tuner_writereg(state, 0x05, 0x01);
-+              m88ds3103_tuner_writereg(state, 0x62, 0xb5);
-+              m88ds3103_tuner_writereg(state, 0x07, 0x02);
-+              m88ds3103_tuner_writereg(state, 0x08, 0x01);
-+      }
-+      else if(state->tuner_id == TS2022_ID){
-+              /* TS2022 init */
-+              m88ds3103_tuner_writereg(state, 0x62, 0x6c);
-+              msleep(2);
-+              m88ds3103_tuner_writereg(state, 0x42, 0x6c);
-+              msleep(2);
-+              m88ds3103_tuner_writereg(state, 0x7d, 0x9d);
-+              m88ds3103_tuner_writereg(state, 0x7c, 0x9a);
-+              m88ds3103_tuner_writereg(state, 0x7a, 0x76);
-+
-+              m88ds3103_tuner_writereg(state, 0x3b, 0x01);
-+              m88ds3103_tuner_writereg(state, 0x63, 0x88);
-+
-+              m88ds3103_tuner_writereg(state, 0x61, 0x85);
-+              m88ds3103_tuner_writereg(state, 0x22, 0x30);
-+              m88ds3103_tuner_writereg(state, 0x30, 0x40);
-+              m88ds3103_tuner_writereg(state, 0x20, 0x23);
-+              m88ds3103_tuner_writereg(state, 0x24, 0x02);
-+              m88ds3103_tuner_writereg(state, 0x12, 0xa0);    
-+      }
-+              
-+      if(state->demod_id == DS3103_ID){
-+              m88ds3103_writereg(state, 0x07, 0xe0);
-+              m88ds3103_writereg(state, 0x07, 0x00);
-+              msleep(1);              
-+      }
-+      m88ds3103_writereg(state, 0xb2, 0x01);
-+      
-+      /* Load the firmware if required */
-+      ret = m88ds3103_load_firmware(fe);
-+      if (ret != 0){
-+              printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
-+              return ret;
-+      }
-+      if(state->demod_id == DS3103_ID){
-+              m88ds3103_writereg(state, 0x4d, 0xfd & m88ds3103_readreg(state, 0x4d));
-+              m88ds3103_writereg(state, 0x30, 0xef & m88ds3103_readreg(state, 0x30));         
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-+ * Initialise or wake up device
-+ */
-+static int m88ds3103_initfe(struct dvb_frontend *fe)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+      u8 val;
-+
-+      dprintk("%s()\n", __func__);
-+
-+      /* 1st step to wake up demod */
-+      m88ds3103_writereg(state, 0x08, 0x01 | m88ds3103_readreg(state, 0x08));
-+      m88ds3103_writereg(state, 0x04, 0xfe & m88ds3103_readreg(state, 0x04));
-+      m88ds3103_writereg(state, 0x23, 0xef & m88ds3103_readreg(state, 0x23));
-+      
-+      /* 2nd step to wake up tuner */
-+      val = m88ds3103_tuner_readreg(state, 0x00) & 0xff;
-+      if((val & 0x01) == 0){
-+              m88ds3103_tuner_writereg(state, 0x00, 0x01);
-+              msleep(50);
-+      }
-+      m88ds3103_tuner_writereg(state, 0x00, 0x03);
-+      msleep(50);
-+      
-+      return 0;       
-+}
-+
-+/* Put device to sleep */
-+static int m88ds3103_sleep(struct dvb_frontend *fe)
-+{
-+      struct m88ds3103_state *state = fe->demodulator_priv;
-+
-+      dprintk("%s()\n", __func__);
-+      
-+      /* 1st step to sleep tuner */
-+      m88ds3103_tuner_writereg(state, 0x00, 0x00);
-+      
-+      /* 2nd step to sleep demod */
-+      m88ds3103_writereg(state, 0x08, 0xfe & m88ds3103_readreg(state, 0x08));
-+      m88ds3103_writereg(state, 0x04, 0x01 | m88ds3103_readreg(state, 0x04));
-+      m88ds3103_writereg(state, 0x23, 0x10 | m88ds3103_readreg(state, 0x23));
-+      
-+
-+      return 0;
-+}
-+
-+static struct dvb_frontend_ops m88ds3103_ops = {
-+      .delsys = { SYS_DVBS, SYS_DVBS2},
-+      .info = {
-+              .name = "Montage DS3103/TS2022",
-+              .type = FE_QPSK,
-+              .frequency_min = 950000,
-+              .frequency_max = 2150000,
-+              .frequency_stepsize = 1011, /* kHz for QPSK frontends */
-+              .frequency_tolerance = 5000,
-+              .symbol_rate_min = 1000000,
-+              .symbol_rate_max = 45000000,
-+              .caps = FE_CAN_INVERSION_AUTO |
-+                      FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-+                      FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-+                      FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-+                      FE_CAN_2G_MODULATION |
-+                      FE_CAN_QPSK | FE_CAN_RECOVER
-+      },
-+
-+      .release = m88ds3103_release,
-+
-+      .init = m88ds3103_initfe,
-+      .sleep = m88ds3103_sleep,
-+      .read_status = m88ds3103_read_status,
-+      .read_ber = m88ds3103_read_ber,
-+      .read_signal_strength = m88ds3103_read_signal_strength,
-+      .read_snr = m88ds3103_read_snr,
-+      .read_ucblocks = m88ds3103_read_ucblocks,
-+      .set_tone = m88ds3103_set_tone,
-+      .set_voltage = m88ds3103_set_voltage,
-+      .diseqc_send_master_cmd = m88ds3103_send_diseqc_msg,
-+      .diseqc_send_burst = m88ds3103_diseqc_send_burst,
-+      .get_frontend_algo = m88ds3103_get_algo,
-+      .tune = m88ds3103_tune,
-+      .set_frontend = m88ds3103_set_frontend,
-+};
-+
-+MODULE_DESCRIPTION("DVB Frontend module for Montage DS3103/TS2022 hardware");
-+MODULE_AUTHOR("Max nibble");
-+MODULE_LICENSE("GPL");
-diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.h v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.h
---- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103.h 1970-01-01 01:00:00.000000000 +0100
-+++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103.h     2012-11-24 13:34:43.716679774 +0100
-@@ -0,0 +1,53 @@
-+/*
-+    Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#ifndef M88DS3103_H
-+#define M88DS3103_H
-+
-+#include <linux/dvb/frontend.h>
-+
-+struct m88ds3103_config {
-+      /* the demodulator's i2c address */
-+      u8 demod_address;
-+      u8 ci_mode;
-+      u8 pin_ctrl;
-+      u8 ts_mode; /* 0: Parallel, 1: Serial */
-+
-+      /* Set device param to start dma */
-+      int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
-+    /* Start to transfer data */
-+    int (*start_ctrl)(struct dvb_frontend *fe);
-+    /* Set LNB voltage */
-+    int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
-+};
-+
-+#if defined(CONFIG_DVB_M88DS3103) || \
-+      (defined(CONFIG_DVB_M88DS3103_MODULE) && defined(MODULE))
-+extern struct dvb_frontend *m88ds3103_attach(
-+       const struct m88ds3103_config *config,
-+       struct i2c_adapter *i2c);
-+#else
-+static inline struct dvb_frontend *m88ds3103_attach(
-+       const struct m88ds3103_config *config,
-+       struct i2c_adapter *i2c)
-+{
-+      printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-+      return NULL;
-+}
-+#endif /* CONFIG_DVB_M88DS3103 */
-+#endif /* M88DS3103_H */
-diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103_priv.h v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103_priv.h
---- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/m88ds3103_priv.h    1970-01-01 01:00:00.000000000 +0100
-+++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/m88ds3103_priv.h        2012-11-24 13:34:43.716679774 +0100
-@@ -0,0 +1,403 @@
-+/*
-+    Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License
-+    along with this program; if not, write to the Free Software
-+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#ifndef M88DS3103_PRIV_H
-+#define M88DS3103_PRIV_H
-+
-+#define FW_DOWN_SIZE 32
-+#define FW_DOWN_LOOP (8192/FW_DOWN_SIZE)
-+#define DS3103_DEFAULT_FIRMWARE "dvb-fe-ds3103.fw"
-+#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds300x.fw"
-+#define MT_FE_MCLK_KHZ 96000 /* in kHz */
-+#define MT_FE_CRYSTAL_KHZ   27000 /* in kHz */
-+#define FREQ_OFFSET_AT_SMALL_SYM_RATE_KHz 3000
-+#define DS3000_ID     0x3000
-+#define DS3103_ID     0x3103
-+#define TS2020_ID     0x2020
-+#define TS2022_ID     0x2022
-+#define UNKNOW_ID     0x0000
-+
-+struct m88ds3103_state {
-+      struct i2c_adapter *i2c;
-+      const struct m88ds3103_config *config;
-+      
-+      struct dvb_frontend frontend;
-+      
-+      u32 preBer;
-+      u8 skip_fw_load;        
-+      u8 first_lock; /* The first time of signal lock */
-+      u16 demod_id; /* demod chip type */
-+      u16 tuner_id; /* tuner chip type */
-+      fe_delivery_system_t delivery_system;
-+};
-+
-+/* For M88DS3103 demod dvbs mode.*/
-+static u8 ds3103_dvbs_init_tab[] = {
-+      0x23, 0x07,
-+      0x08, 0x03,
-+      0x0c, 0x02,
-+      0x21, 0x54,
-+      0x25, 0x82,
-+      0x27, 0x31,
-+      0x30, 0x08,
-+      0x31, 0x40,
-+      0x32, 0x32,
-+      0x33, 0x35,
-+      0x35, 0xff,
-+      0x3a, 0x00,
-+      0x37, 0x10,
-+      0x38, 0x10,
-+      0x39, 0x02,
-+      0x42, 0x60,
-+      0x4a, 0x80,
-+      0x4b, 0x04,
-+      0x4d, 0x91,
-+      0x5d, 0xc8,
-+      0x50, 0x36,
-+      0x51, 0x36,
-+      0x52, 0x36,
-+      0x53, 0x36,
-+      0x63, 0x0f,
-+      0x64, 0x30,
-+      0x65, 0x40,
-+      0x68, 0x26,
-+      0x69, 0x4c,
-+      0x70, 0x20,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x40,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x60,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x80,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0xa0,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x1f,
-+      0x76, 0x38,
-+      0x77, 0xa6,
-+      0x78, 0x0c,
-+      0x79, 0x80,
-+      0x7f, 0x14,
-+      0x7c, 0x00,
-+      0xae, 0x82,
-+      0x80, 0x64,
-+      0x81, 0x66,
-+      0x82, 0x44,
-+      0x85, 0x04,
-+      0xcd, 0xf4,
-+      0x90, 0x33,
-+      0xa0, 0x44,
-+      0xc0, 0x08,
-+      0xc3, 0x10,
-+      0xc4, 0x08,
-+      0xc5, 0xf0,
-+      0xc6, 0xff,
-+      0xc7, 0x00,
-+      0xc8, 0x1a,
-+      0xc9, 0x80,
-+      0xe0, 0xf8,
-+      0xe6, 0x8b,
-+      0xd0, 0x40,
-+      0xf8, 0x20,
-+      0xfa, 0x0f,
-+      0x00, 0x00,
-+      0xbd, 0x01,
-+      0xb8, 0x00,
-+};
-+/* For M88DS3103 demod dvbs2 mode.*/
-+static u8 ds3103_dvbs2_init_tab[] = {
-+      0x23, 0x07,
-+      0x08, 0x07,
-+      0x0c, 0x02,
-+      0x21, 0x54,
-+      0x25, 0x82,
-+      0x27, 0x31,
-+      0x30, 0x08,
-+      0x32, 0x32,
-+      0x33, 0x35,
-+      0x35, 0xff,
-+      0x3a, 0x00,
-+      0x37, 0x10,
-+      0x38, 0x10,
-+      0x39, 0x02,
-+      0x42, 0x60,
-+      0x4a, 0x80,
-+      0x4b, 0x04,
-+      0x4d, 0x91,
-+      0x5d, 0xc8,
-+      0x50, 0x36,
-+      0x51, 0x36,
-+      0x52, 0x36,
-+      0x53, 0x36,
-+      0x63, 0x0f,
-+      0x64, 0x10,
-+      0x65, 0x20,
-+      0x68, 0x46,
-+      0x69, 0xcd,
-+      0x70, 0x20,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x40,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x60,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x80,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0xa0,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x1f,
-+      0x76, 0x38,
-+      0x77, 0xa6,
-+      0x78, 0x0c,
-+      0x79, 0x80,
-+      0x7f, 0x14,
-+      0x85, 0x08,
-+      0xcd, 0xf4,
-+      0x90, 0x33,
-+      0x86, 0x00,
-+      0x87, 0x0f,
-+      0x89, 0x00,
-+      0x8b, 0x44,
-+      0x8c, 0x66,
-+      0x9d, 0xc1,
-+      0x8a, 0x10,
-+      0xad, 0x40,
-+      0xa0, 0x44,
-+      0xc0, 0x08,
-+      0xc1, 0x10,
-+      0xc2, 0x08,
-+      0xc3, 0x10,
-+      0xc4, 0x08,
-+      0xc5, 0xf0,
-+      0xc6, 0xff,
-+      0xc7, 0x00,
-+      0xc8, 0x1a,
-+      0xc9, 0x80,
-+      0xca, 0x23,
-+      0xcb, 0x24,
-+      0xcc, 0xf4,
-+      0xce, 0x74,
-+      0x00, 0x00,
-+      0xbd, 0x01,
-+      0xb8, 0x00,
-+};
-+
-+/* For M88DS3000 demod dvbs mode.*/
-+static u8 ds3000_dvbs_init_tab[] = {
-+      0x23, 0x05,
-+      0x08, 0x03,
-+      0x0c, 0x02,
-+      0x21, 0x54,
-+      0x25, 0x82,
-+      0x27, 0x31,
-+      0x30, 0x08,
-+      0x31, 0x40,
-+      0x32, 0x32,
-+      0x33, 0x35,
-+      0x35, 0xff,
-+      0x3a, 0x00,
-+      0x37, 0x10,
-+      0x38, 0x10,
-+      0x39, 0x02,
-+      0x42, 0x60,
-+      0x4a, 0x40,
-+      0x4b, 0x04,
-+      0x4d, 0x91,
-+      0x5d, 0xc8,
-+      0x50, 0x77,
-+      0x51, 0x77,
-+      0x52, 0x36,
-+      0x53, 0x36,
-+      0x56, 0x01,
-+      0x63, 0x47,
-+      0x64, 0x30,
-+      0x65, 0x40,
-+      0x68, 0x26,
-+      0x69, 0x4c,
-+      0x70, 0x20,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x40,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x60,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x80,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0xa0,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x1f,
-+      0x76, 0x00,
-+      0x77, 0xd1,
-+      0x78, 0x0c,
-+      0x79, 0x80,
-+      0x7f, 0x04,
-+      0x7c, 0x00,
-+      0x80, 0x86,
-+      0x81, 0xa6,
-+      0x85, 0x04,
-+      0xcd, 0xf4,
-+      0x90, 0x33,
-+      0xa0, 0x44,
-+      0xc0, 0x18,
-+      0xc3, 0x10,
-+      0xc4, 0x08,
-+      0xc5, 0x80,
-+      0xc6, 0x80,
-+      0xc7, 0x0a,
-+      0xc8, 0x1a,
-+      0xc9, 0x80,
-+      0xfe, 0xb6,
-+      0xe0, 0xf8,
-+      0xe6, 0x8b,
-+      0xd0, 0x40,
-+      0xf8, 0x20,
-+      0xfa, 0x0f,
-+      0xad, 0x20,
-+      0xae, 0x07,
-+      0xb8, 0x00,
-+};
-+
-+/* For M88DS3000 demod dvbs2 mode.*/
-+static u8 ds3000_dvbs2_init_tab[] = {
-+      0x23, 0x0f,
-+      0x08, 0x07,
-+      0x0c, 0x02,
-+      0x21, 0x54,
-+      0x25, 0x82,
-+      0x27, 0x31,
-+      0x30, 0x08,
-+      0x31, 0x32,
-+      0x32, 0x32,
-+      0x33, 0x35,
-+      0x35, 0xff,
-+      0x3a, 0x00,
-+      0x37, 0x10,
-+      0x38, 0x10,
-+      0x39, 0x02,
-+      0x42, 0x60,
-+      0x4a, 0x80,
-+      0x4b, 0x04,
-+      0x4d, 0x91,
-+      0x5d, 0x88,
-+      0x50, 0x36,
-+      0x51, 0x36,
-+      0x52, 0x36,
-+      0x53, 0x36,
-+      0x63, 0x60,
-+      0x64, 0x10,
-+      0x65, 0x10,
-+      0x68, 0x04,
-+      0x69, 0x29,
-+      0x70, 0x20,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x40,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x60,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x80,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0xa0,
-+      0x71, 0x70,
-+      0x72, 0x04,
-+      0x73, 0x00,
-+      0x70, 0x1f,
-+      0xa0, 0x44,
-+      0xc0, 0x08,
-+      0xc1, 0x10,
-+      0xc2, 0x08,
-+      0xc3, 0x10,
-+      0xc4, 0x08,
-+      0xc5, 0xf0,
-+      0xc6, 0xf0,
-+      0xc7, 0x0a,
-+      0xc8, 0x1a,
-+      0xc9, 0x80,
-+      0xca, 0x23,
-+      0xcb, 0x24,
-+      0xce, 0x74,
-+      0x56, 0x01,
-+      0x90, 0x03,
-+      0x76, 0x80,
-+      0x77, 0x42,
-+      0x78, 0x0a,
-+      0x79, 0x80,
-+      0xad, 0x40,
-+      0xae, 0x07,
-+      0x7f, 0xd4,
-+      0x7c, 0x00,
-+      0x80, 0xa8,
-+      0x81, 0xda,
-+      0x7c, 0x01,
-+      0x80, 0xda,
-+      0x81, 0xec,
-+      0x7c, 0x02,
-+      0x80, 0xca,
-+      0x81, 0xeb,
-+      0x7c, 0x03,
-+      0x80, 0xba,
-+      0x81, 0xdb,
-+      0x85, 0x08,
-+      0x86, 0x00,
-+      0x87, 0x02,
-+      0x89, 0x80,
-+      0x8b, 0x44,
-+      0x8c, 0xaa,
-+      0x8a, 0x10,
-+      0xba, 0x00,
-+      0xf5, 0x04,
-+      0xd2, 0x32,
-+      0xb8, 0x00,
-+};
-+
-+#endif /* M88DS3103_PRIV_H */
-diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Makefile v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Makefile
---- v4l-dvb-20120916.ORG/linux/drivers/media/dvb-frontends/Makefile    2012-08-17 05:45:27.000000000 +0200
-+++ v4l-dvb-20120916/linux/drivers/media/dvb-frontends/Makefile        2012-11-24 13:34:43.716679774 +0100
-@@ -102,4 +102,7 @@
- obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
- obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
- obj-$(CONFIG_DVB_AF9033) += af9033.o
-+obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o
-+
-+
-diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/Makefile v4l-dvb-20120916/linux/drivers/media/rc/keymaps/Makefile
---- v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/Makefile       2012-05-21 05:45:41.000000000 +0200
-+++ v4l-dvb-20120916/linux/drivers/media/rc/keymaps/Makefile   2012-11-24 13:34:43.716679774 +0100
-@@ -27,6 +27,7 @@
-                       rc-dm1105-nec.o \
-                       rc-dntv-live-dvb-t.o \
-                       rc-dntv-live-dvbt-pro.o \
-+                      rc-dvbsky.o \
-                       rc-em-terratec.o \
-                       rc-encore-enltv2.o \
-                       rc-encore-enltv.o \
-diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/rc-dvbsky.c v4l-dvb-20120916/linux/drivers/media/rc/keymaps/rc-dvbsky.c
---- v4l-dvb-20120916.ORG/linux/drivers/media/rc/keymaps/rc-dvbsky.c    1970-01-01 01:00:00.000000000 +0100
-+++ v4l-dvb-20120916/linux/drivers/media/rc/keymaps/rc-dvbsky.c        2012-11-24 13:34:43.716679774 +0100
-@@ -0,0 +1,78 @@
-+/* rc-dvbsky.c - Keytable for Dvbsky Remote Controllers
-+ *
-+ * keymap imported from ir-keymaps.c
-+ *
-+ *
-+ * Copyright (c) 2010-2011 by Mauro Carvalho Chehab <mchehab@redhat.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ */
-+
-+#include <media/rc-map.h>
-+#include <linux/module.h>
-+/*
-+ * This table contains the complete RC5 code, instead of just the data part
-+ */
-+
-+static struct rc_map_table rc5_dvbsky[] = {
-+      { 0x0000, KEY_0 },
-+      { 0x0001, KEY_1 },
-+      { 0x0002, KEY_2 },
-+      { 0x0003, KEY_3 },
-+      { 0x0004, KEY_4 },
-+      { 0x0005, KEY_5 },
-+      { 0x0006, KEY_6 },
-+      { 0x0007, KEY_7 },
-+      { 0x0008, KEY_8 },
-+      { 0x0009, KEY_9 },      
-+      { 0x000a, KEY_MUTE },
-+      { 0x000d, KEY_OK },
-+      { 0x000b, KEY_STOP },
-+      { 0x000c, KEY_EXIT },   
-+      { 0x000e, KEY_CAMERA }, /*Snap shot*/
-+      { 0x000f, KEY_SUBTITLE }, /*PIP*/
-+      { 0x0010, KEY_VOLUMEUP },
-+      { 0x0011, KEY_VOLUMEDOWN },
-+      { 0x0012, KEY_FAVORITES },
-+      { 0x0013, KEY_LIST }, /*Info*/
-+      { 0x0016, KEY_PAUSE },
-+      { 0x0017, KEY_PLAY },
-+      { 0x001f, KEY_RECORD },
-+      { 0x0020, KEY_CHANNELDOWN },
-+      { 0x0021, KEY_CHANNELUP },
-+      { 0x0025, KEY_POWER2 },
-+      { 0x0026, KEY_REWIND },
-+      { 0x0027, KEY_FASTFORWARD },
-+      { 0x0029, KEY_LAST },
-+      { 0x002b, KEY_MENU },   
-+      { 0x002c, KEY_EPG },
-+      { 0x002d, KEY_ZOOM },   
-+};
-+
-+static struct rc_map_list rc5_dvbsky_map = {
-+      .map = {
-+              .scan    = rc5_dvbsky,
-+              .size    = ARRAY_SIZE(rc5_dvbsky),
-+              .rc_type = RC_TYPE_RC5,
-+              .name    = RC_MAP_DVBSKY,
-+      }
-+};
-+
-+static int __init init_rc_map_rc5_dvbsky(void)
-+{
-+      return rc_map_register(&rc5_dvbsky_map);
-+}
-+
-+static void __exit exit_rc_map_rc5_dvbsky(void)
-+{
-+      rc_map_unregister(&rc5_dvbsky_map);
-+}
-+
-+module_init(init_rc_map_rc5_dvbsky)
-+module_exit(exit_rc_map_rc5_dvbsky)
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
-diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/dw2102.c v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/dw2102.c
---- v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/dw2102.c      2012-08-14 05:45:22.000000000 +0200
-+++ v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/dw2102.c  2012-11-24 15:44:13.269971182 +0100
-@@ -3,6 +3,7 @@
-  *    TeVii S600, S630, S650, S660, S480,
-  *    Prof 1100, 7500,
-  *    Geniatech SU3000 Cards
-+ *    Bestunar US683x HD, DVBsky S860, S960 USB
-  * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by)
-  *
-  *    This program is free software; you can redistribute it and/or modify it
-@@ -19,6 +20,7 @@
- #include "stb6000.h"
- #include "eds1547.h"
- #include "cx24116.h"
-+#include "m88ds3103.h"
- #include "tda1002x.h"
- #include "mt312.h"
- #include "zl10039.h"
-@@ -786,7 +788,7 @@
-       struct su3000_state *state = (struct su3000_state *)d->priv;
-       u8 obuf[] = {0xde, 0};
--      info("%s: %d, initialized %d\n", __func__, i, state->initialized);
-+      info("%s: %d, initialized %d", __func__, i, state->initialized);
-       if (i && !state->initialized) {
-               state->initialized = 1;
-@@ -824,7 +826,40 @@
-               else
-                       mac[i] = ibuf[0];
--              debug_dump(mac, 6, printk);
-+              debug_dump(mac, 6, deb_xfer);
-+      }
-+
-+      return 0;
-+}
-+
-+static int dvbsky_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
-+{
-+      int i;
-+      u8 obuf[] = { 0x1e, 0x00 };
-+      u8 ibuf[] = { 0 };
-+      struct i2c_msg msg[] = {
-+              {
-+                      .addr = 0x51,
-+                      .flags = 0,
-+                      .buf = obuf,
-+                      .len = 2,
-+              }, {
-+                      .addr = 0x51,
-+                      .flags = I2C_M_RD,
-+                      .buf = ibuf,
-+                      .len = 1,
-+
-+              }
-+      };
-+
-+      for (i = 0; i < 6; i++) {
-+              obuf[1] = i;
-+              if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
-+                      break;
-+              else
-+                      mac[i] = ibuf[0];
-+
-+              debug_dump(mac, 6, deb_xfer);
-       }
-       return 0;
-@@ -835,7 +870,7 @@
-                                struct dvb_usb_device_description **desc,
-                                int *cold)
- {
--      info("%s\n", __func__);
-+      info("%s", __func__);
-       *cold = 0;
-       return 0;
-@@ -878,6 +913,43 @@
-       return 0;
- }
-+static int bstusb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
-+{
-+
-+      struct dvb_usb_adapter *udev_adap =
-+              (struct dvb_usb_adapter *)(fe->dvb->priv);
-+
-+      u8 obuf[3] = { 0xe, 0x80, 0 };
-+      u8 ibuf[] = { 0 };
-+
-+      //info("US6830: %s!", __func__);
-+
-+      if (voltage == SEC_VOLTAGE_OFF)
-+              obuf[2] = 0;
-+      else
-+              obuf[2] = 1;
-+
-+      if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 1, 0) < 0)
-+              err("command 0x0e transfer failed.");
-+
-+      return 0;
-+}
-+
-+static int bstusb_restart(struct dvb_frontend *fe)
-+{
-+
-+      struct dvb_usb_adapter *udev_adap =
-+              (struct dvb_usb_adapter *)(fe->dvb->priv);
-+
-+      u8 obuf[3] = { 0x36, 3, 0 };
-+      u8 ibuf[] = { 0 };
-+
-+      if (dvb_usb_generic_rw(udev_adap->dev, obuf, 3, ibuf, 0, 0) < 0)
-+              err("command 0x36 transfer failed.");
-+
-+      return 0;
-+}
-+
- static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
- {
-       static u8 led_off[] = { 0 };
-@@ -983,6 +1055,24 @@
-       .ci_mode = 1,
- };
-+static struct m88ds3103_config US6830_ds3103_config = {
-+      .demod_address = 0x68,
-+      .ci_mode = 1,
-+      .pin_ctrl = 0x83,
-+      .ts_mode = 0,
-+      .start_ctrl = bstusb_restart,
-+      .set_voltage = bstusb_set_voltage,
-+};
-+
-+static struct m88ds3103_config US6832_ds3103_config = {
-+      .demod_address = 0x68,
-+      .ci_mode = 1,
-+      .pin_ctrl = 0x80,
-+      .ts_mode = 0,
-+      .start_ctrl = bstusb_restart,
-+      .set_voltage = bstusb_set_voltage,
-+};
-+
- static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
- {
-       struct dvb_tuner_ops *tuner_ops = NULL;
-@@ -1000,7 +1090,7 @@
-                               tuner_ops->set_bandwidth = stb6100_set_bandw;
-                               tuner_ops->get_bandwidth = stb6100_get_bandw;
-                               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
--                              info("Attached STV0900+STB6100!\n");
-+                              info("Attached STV0900+STB6100!");
-                               return 0;
-                       }
-               }
-@@ -1014,7 +1104,7 @@
-                                       &dw2104_stv6110_config,
-                                       &d->dev->i2c_adap)) {
-                               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
--                              info("Attached STV0900+STV6110A!\n");
-+                              info("Attached STV0900+STV6110A!");
-                               return 0;
-                       }
-               }
-@@ -1025,7 +1115,7 @@
-                               &d->dev->i2c_adap);
-               if (d->fe_adap[0].fe != NULL) {
-                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
--                      info("Attached cx24116!\n");
-+                      info("Attached cx24116!");
-                       return 0;
-               }
-       }
-@@ -1034,7 +1124,7 @@
-                       &d->dev->i2c_adap);
-       if (d->fe_adap[0].fe != NULL) {
-               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
--              info("Attached DS3000!\n");
-+              info("Attached DS3000!");
-               return 0;
-       }
-@@ -1053,7 +1143,7 @@
-                                       &d->dev->i2c_adap);
-               if (d->fe_adap[0].fe != NULL) {
-                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
--                      info("Attached si21xx!\n");
-+                      info("Attached si21xx!");
-                       return 0;
-               }
-       }
-@@ -1065,7 +1155,7 @@
-                       if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
-                                       &d->dev->i2c_adap)) {
-                               d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
--                              info("Attached stv0288!\n");
-+                              info("Attached stv0288!");
-                               return 0;
-                       }
-               }
-@@ -1077,7 +1167,7 @@
-                                       &d->dev->i2c_adap);
-               if (d->fe_adap[0].fe != NULL) {
-                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
--                      info("Attached stv0299!\n");
-+                      info("Attached stv0299!");
-                       return 0;
-               }
-       }
-@@ -1089,7 +1179,7 @@
-       d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
-                               &d->dev->i2c_adap, 0x48);
-       if (d->fe_adap[0].fe != NULL) {
--              info("Attached tda10023!\n");
-+              info("Attached tda10023!");
-               return 0;
-       }
-       return -EIO;
-@@ -1103,7 +1193,7 @@
-               if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
-                               &d->dev->i2c_adap)) {
-                       d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
--                      info("Attached zl100313+zl10039!\n");
-+                      info("Attached zl100313+zl10039!");
-                       return 0;
-               }
-       }
-@@ -1128,7 +1218,7 @@
-       dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
--      info("Attached stv0288+stb6000!\n");
-+      info("Attached stv0288+stb6000!");
-       return 0;
-@@ -1150,7 +1240,7 @@
-       dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
--      info("Attached ds3000+ds2020!\n");
-+      info("Attached ds3000+ds2020!");
-       return 0;
- }
-@@ -1168,7 +1258,7 @@
-       dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
--      info("Attached STV0900+STB6100A!\n");
-+      info("Attached STV0900+STB6100A!");
-       return 0;
- }
-@@ -1205,7 +1295,88 @@
-       if (d->fe_adap[0].fe == NULL)
-               return -EIO;
--      info("Attached DS3000!\n");
-+      info("Attached DS3000!");
-+
-+      return 0;
-+}
-+
-+static int US6830_frontend_attach(struct dvb_usb_adapter *d)
-+{
-+      u8 obuf[3] = { 0xe, 0x04, 1 };
-+      u8 ibuf[] = { 0 };
-+
-+      info("US6830: %s!\n", __func__);
-+
-+      if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
-+              err("command 0x0e transfer failed.");
-+
-+      obuf[0] = 0xe;
-+      obuf[1] = 0x83;
-+      obuf[2] = 0;
-+      
-+      if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
-+              err("command 0x0e transfer failed.");
-+
-+      msleep(20);
-+
-+      obuf[0] = 0xe;
-+      obuf[1] = 0x83;
-+      obuf[2] = 1;
-+
-+      if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
-+              err("command 0x0e transfer failed.");
-+
-+      obuf[0] = 0x51;
-+
-+      if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
-+              err("command 0x51 transfer failed.");
-+
-+      d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6830_ds3103_config,
-+                                      &d->dev->i2c_adap);
-+      if (d->fe_adap[0].fe == NULL)
-+              return -EIO;
-+
-+      info("Attached M88DS3103!");
-+
-+      return 0;
-+}
-+
-+static int US6832_frontend_attach(struct dvb_usb_adapter *d)
-+{
-+      u8 obuf[3] = { 0xe, 0x04, 1 };
-+      u8 ibuf[] = { 0 };
-+
-+      info("US6832: %s!", __func__);
-+
-+      if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
-+              err("command 0x0e transfer failed.");
-+
-+      obuf[0] = 0xe;
-+      obuf[1] = 0x83;
-+      obuf[2] = 0;
-+      
-+      if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
-+              err("command 0x0e transfer failed.");
-+
-+      msleep(20);
-+      obuf[0] = 0xe;
-+      obuf[1] = 0x83;
-+      obuf[2] = 1;
-+
-+      if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
-+              err("command 0x0e transfer failed.");
-+
-+      obuf[0] = 0x51;
-+
-+      if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
-+              err("command 0x51 transfer failed.");
-+
-+      d->fe_adap[0].fe = dvb_attach(m88ds3103_attach, &US6832_ds3103_config,
-+                                      &d->dev->i2c_adap);
-+      if (d->fe_adap[0].fe == NULL)
-+              return -EIO;
-+
-+      info("Attached M88DS3103!");
-       return 0;
- }
-@@ -1447,6 +1618,9 @@
-       TEVII_S480_1,
-       TEVII_S480_2,
-       X3M_SPC1400HD,
-+      BST_US6830HD,
-+      BST_US6831HD,
-+      BST_US6832HD,
- };
- static struct usb_device_id dw2102_table[] = {
-@@ -1465,6 +1639,9 @@
-       [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
-       [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
-       [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
-+      [BST_US6830HD] = {USB_DEVICE(0x0572, 0x6830)},
-+      [BST_US6831HD] = {USB_DEVICE(0x0572, 0x6831)},
-+      [BST_US6832HD] = {USB_DEVICE(0x0572, 0x6832)},
-       { }
- };
-@@ -1870,6 +2047,106 @@
-       }
- };
-+static struct dvb_usb_device_properties US6830_properties = {
-+      .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-+      .usb_ctrl = DEVICE_SPECIFIC,
-+      .size_of_priv = sizeof(struct su3000_state),
-+      .power_ctrl = su3000_power_ctrl,
-+      .num_adapters = 1,
-+      .identify_state = su3000_identify_state,
-+      .i2c_algo = &su3000_i2c_algo,
-+
-+      .rc.legacy = {
-+              .rc_map_table = rc_map_su3000_table,
-+              .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
-+              .rc_interval = 150,
-+              .rc_query = dw2102_rc_query,
-+      },
-+
-+      .read_mac_address = dvbsky_read_mac_address,
-+
-+      .generic_bulk_ctrl_endpoint = 0x01,
-+      
-+      .adapter = {
-+              {
-+              .num_frontends = 1,
-+              .fe = {{
-+                      .streaming_ctrl   = su3000_streaming_ctrl,
-+                      .frontend_attach  = US6830_frontend_attach,
-+                      .stream = {
-+                              .type = USB_BULK,
-+                              .count = 8,
-+                              .endpoint = 0x82,
-+                              .u = {
-+                                      .bulk = {
-+                                              .buffersize = 4096,
-+                                      }
-+                              }
-+                      }
-+              }},
-+              }
-+      },
-+      .num_device_descs = 2,
-+      .devices = {
-+              { "Bestunar US6830 HD",
-+                      { &dw2102_table[BST_US6830HD], NULL },
-+                      { NULL },
-+              },
-+              { "Bestunar US6831 HD",
-+                      { &dw2102_table[BST_US6831HD], NULL },
-+                      { NULL },
-+              },                              
-+      }
-+};
-+
-+static struct dvb_usb_device_properties US6832_properties = {
-+      .caps = DVB_USB_IS_AN_I2C_ADAPTER,
-+      .usb_ctrl = DEVICE_SPECIFIC,
-+      .size_of_priv = sizeof(struct su3000_state),
-+      .power_ctrl = su3000_power_ctrl,
-+      .num_adapters = 1,
-+      .identify_state = su3000_identify_state,
-+      .i2c_algo = &su3000_i2c_algo,
-+
-+      .rc.legacy = {
-+              .rc_map_table = rc_map_su3000_table,
-+              .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
-+              .rc_interval = 150,
-+              .rc_query = dw2102_rc_query,
-+      },
-+
-+      .read_mac_address = dvbsky_read_mac_address,
-+
-+      .generic_bulk_ctrl_endpoint = 0x01,
-+
-+      .adapter = {
-+              {
-+              .num_frontends = 1,
-+              .fe = {{
-+                      .streaming_ctrl   = su3000_streaming_ctrl,
-+                      .frontend_attach  = US6832_frontend_attach,
-+                      .stream = {
-+                              .type = USB_BULK,
-+                              .count = 8,
-+                              .endpoint = 0x82,
-+                              .u = {
-+                                      .bulk = {
-+                                              .buffersize = 4096,
-+                                      }
-+                              }
-+                      }
-+              }},
-+              }
-+      },
-+      .num_device_descs = 1,
-+      .devices = {
-+              { "Bestunar US6832 HD",
-+                      { &dw2102_table[BST_US6832HD], NULL },
-+                      { NULL },
-+              },
-+      }
-+};
-+
- static int dw2102_probe(struct usb_interface *intf,
-               const struct usb_device_id *id)
- {
-@@ -1926,6 +2203,10 @@
-           0 == dvb_usb_device_init(intf, p7500,
-                       THIS_MODULE, NULL, adapter_nr) ||
-           0 == dvb_usb_device_init(intf, &su3000_properties,
-+                      THIS_MODULE, NULL, adapter_nr) ||
-+          0 == dvb_usb_device_init(intf, &US6830_properties,
-+                      THIS_MODULE, NULL, adapter_nr) ||
-+          0 == dvb_usb_device_init(intf, &US6832_properties,
-                                    THIS_MODULE, NULL, adapter_nr))
-               return 0;
-diff -Naur v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/Kconfig v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/Kconfig
---- v4l-dvb-20120916.ORG/linux/drivers/media/usb/dvb-usb/Kconfig       2012-08-22 05:45:23.000000000 +0200
-+++ v4l-dvb-20120916/linux/drivers/media/usb/dvb-usb/Kconfig   2012-11-24 13:34:43.716679774 +0100
-@@ -1,3 +1,4 @@
-++     select DVB_M88DS3103 if !DVB_FE_CUSTOMISE
- config DVB_USB
-       tristate "Support for various USB DVB devices"
-       depends on DVB_CORE && USB && I2C && RC_CORE
-@@ -261,6 +262,7 @@
-       select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
-       select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
-       select DVB_STB6000 if MEDIA_SUBDRV_AUTOSELECT
-+      select DVB_M88DS3103 if MEDIA_SUBDRV_AUTOSELECT
-       select DVB_CX24116 if MEDIA_SUBDRV_AUTOSELECT
-       select DVB_SI21XX if MEDIA_SUBDRV_AUTOSELECT
-       select DVB_TDA10023 if MEDIA_SUBDRV_AUTOSELECT
-diff -Naur v4l-dvb-20120916.ORG/linux/include/media/rc-map.h v4l-dvb-20120916/linux/include/media/rc-map.h
---- v4l-dvb-20120916.ORG/linux/include/media/rc-map.h  2012-05-21 05:45:41.000000000 +0200
-+++ v4l-dvb-20120916/linux/include/media/rc-map.h      2012-11-24 13:34:43.716679774 +0100
-@@ -86,6 +86,7 @@
- #define RC_MAP_DM1105_NEC                "rc-dm1105-nec"
- #define RC_MAP_DNTV_LIVE_DVBT_PRO        "rc-dntv-live-dvbt-pro"
- #define RC_MAP_DNTV_LIVE_DVB_T           "rc-dntv-live-dvb-t"
-+#define RC_MAP_DVBSKY                    "rc-dvbsky"
- #define RC_MAP_EMPTY                     "rc-empty"
- #define RC_MAP_EM_TERRATEC               "rc-em-terratec"
- #define RC_MAP_ENCORE_ENLTV2             "rc-encore-enltv2"
diff --git a/src/patches/v4l-dvb_rtl28xx_add_usb_ids.patch b/src/patches/v4l-dvb_rtl28xx_add_usb_ids.patch
deleted file mode 100644 (file)
index 1dd649a..0000000
+++ /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 (file)
index 8fb8bc4..0000000
+++ /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 (file)
index 4b16125..0000000
+++ /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 (file)
index d8841d8..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-Index: vdr-1.6.0/recording.c
-===================================================================
---- vdr-1.6.0.orig/recording.c
-+++ vdr-1.6.0/recording.c
-@@ -509,8 +509,8 @@ cRecording::cRecording(cTimer *Timer, co
-      Utf8Strn0Cpy(SubtitleBuffer, Subtitle, MAX_SUBTITLE_LENGTH);
-      Subtitle = SubtitleBuffer;
-      }
--  char *macroTITLE   = strstr(Timer->File(), TIMERMACRO_TITLE);
--  char *macroEPISODE = strstr(Timer->File(), TIMERMACRO_EPISODE);
-+  const char *macroTITLE   = strstr(Timer->File(), TIMERMACRO_TITLE);
-+  const char *macroEPISODE = strstr(Timer->File(), TIMERMACRO_EPISODE);
-   if (macroTITLE || macroEPISODE) {
-      name = strdup(Timer->File());
-      name = strreplace(name, TIMERMACRO_TITLE, Title);
-@@ -551,7 +551,7 @@ cRecording::cRecording(const char *FileN
-   sortBuffer = NULL;
-   fileName = strdup(FileName);
-   FileName += strlen(VideoDirectory) + 1;
--  char *p = strrchr(FileName, '/');
-+  const char *p = strrchr(FileName, '/');
-   name = NULL;
-   info = new cRecordingInfo;
-@@ -1022,7 +1022,8 @@ void cRecordings::DelByName(const char *
-   if (recording) {
-      cThreadLock DeletedRecordingsLock(&DeletedRecordings);
-      Del(recording, false);
--     char *ext = strrchr(recording->FileName(), '.');
-+     // wtf?
-+     char *ext = strrchr(const_cast<char*>(recording->FileName()), '.');
-      if (ext) {
-         strncpy(ext, DELEXT, strlen(ext));
-         recording->fileSizeMB = DirSizeMB(recording->FileName());
-Index: vdr-1.6.0/svdrp.c
-===================================================================
---- vdr-1.6.0.orig/svdrp.c
-+++ vdr-1.6.0/svdrp.c
-@@ -736,7 +736,7 @@ void cSVDRP::CmdGRAB(const char *Option)
-      char *strtok_next;
-      FileName = strtok_r(p, delim, &strtok_next);
-      // image type:
--     char *Extension = strrchr(FileName, '.');
-+     const char *Extension = strrchr(FileName, '.');
-      if (Extension) {
-         if (strcasecmp(Extension, ".jpg") == 0 || strcasecmp(Extension, ".jpeg") == 0)
-            Jpeg = true;
-@@ -796,12 +796,12 @@ void cSVDRP::CmdGRAB(const char *Option)
-      if (FileName) {
-         if (grabImageDir) {
-            cString s;
--           char *slash = strrchr(FileName, '/');
-+           char *slash = strrchr(const_cast<char*>(FileName), '/');
-            if (!slash) {
-               s = AddDirectory(grabImageDir, FileName);
-               FileName = s;
-               }
--           slash = strrchr(FileName, '/'); // there definitely is one
-+           slash = strrchr(const_cast<char*>(FileName), '/'); // there definitely is one
-            *slash = 0;
-            char *r = realpath(FileName, RealFileName);
-            *slash = '/';
diff --git a/src/patches/vdr-plugin-epgsearch-gcc44.patch b/src/patches/vdr-plugin-epgsearch-gcc44.patch
deleted file mode 100644 (file)
index 2a92a3b..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-diff -urNad vdr-plugin-epgsearch-0.9.24~/epgsearchsvdrp.c vdr-plugin-epgsearch-0.9.24/epgsearchsvdrp.c
---- vdr-plugin-epgsearch-0.9.24~/epgsearchsvdrp.c      2008-04-13 20:53:44.000000000 +0200
-+++ vdr-plugin-epgsearch-0.9.24/epgsearchsvdrp.c       2009-10-26 20:27:07.000000000 +0100
-@@ -742,12 +742,13 @@
-    {
-       if (*Option) 
-       {
--         char* pipePos = strchr(Option, '|');
-+         const char* pipePos = strchr(Option, '|');
-          if (pipePos)
-          {
--            *pipePos = 0;
--            const char* oldName = Option;
--            const char* newName = pipePos+1;
-+            int index = pipePos - Option;
-+            char* oldName = strdup(Option);
-+            *(oldName + index) = 0;
-+            const char* newName = oldName + index + 1;
-             if (strlen(oldName) > 0 && strlen(newName) > 0)
-             {
-                cChannelGroup *changrp = ChannelGroups.GetGroupByName(Option);
-@@ -769,15 +770,18 @@
-                   }
-                   ChannelGroups.Save();
-                   SearchExts.Save();
-+                  free(oldName);
-                   return cString::sprintf("renamed channel group '%s' to '%s'", oldName, newName);
-                }                  
-                else
-                {
-+                  free(oldName);
-                   ReplyCode = 901;
-                   return cString::sprintf("channel group '%s' not defined", Option);
-                }
-             }
-+            free(oldName);
-          }
-          ReplyCode = 901;
-          return cString("Error in channel group parameters"); 
-diff -urNad vdr-plugin-epgsearch-0.9.24~/epgsearchtools.c vdr-plugin-epgsearch-0.9.24/epgsearchtools.c
---- vdr-plugin-epgsearch-0.9.24~/epgsearchtools.c      2008-04-13 20:53:42.000000000 +0200
-+++ vdr-plugin-epgsearch-0.9.24/epgsearchtools.c       2009-10-26 20:27:07.000000000 +0100
-@@ -743,7 +743,7 @@
-    while(tmp)
-    {
-       // extract a single line
--      char* lf = strchr(tmp, '\n');
-+      const char* lf = strchr(tmp, '\n');
-       char* line = NULL;
-       if (lf)
-       line = strndup(tmp, lf-tmp);
-diff -urNad vdr-plugin-epgsearch-0.9.24~/menu_dirselect.c vdr-plugin-epgsearch-0.9.24/menu_dirselect.c
---- vdr-plugin-epgsearch-0.9.24~/menu_dirselect.c      2008-04-13 20:53:44.000000000 +0200
-+++ vdr-plugin-epgsearch-0.9.24/menu_dirselect.c       2009-10-26 20:27:07.000000000 +0100
-@@ -83,7 +83,7 @@
-       return 1;
-     do
-     {
--      char* pos = strchr(szDir, '~');
-+      const char* pos = strchr(szDir, '~');
-       if (pos)
-       {
-           iLevel++;
-diff -urNad vdr-plugin-epgsearch-0.9.24~/searchtimer_thread.c vdr-plugin-epgsearch-0.9.24/searchtimer_thread.c
---- vdr-plugin-epgsearch-0.9.24~/searchtimer_thread.c  2008-04-28 18:22:31.000000000 +0200
-+++ vdr-plugin-epgsearch-0.9.24/searchtimer_thread.c   2009-10-26 20:27:28.000000000 +0100
-@@ -565,8 +565,8 @@
-    if (!isempty(aux))
-    {
-       tmpaux = strdup(aux);
--      char* begin = strstr(aux, "<epgsearch>");
--      char* end = strstr(aux, "</epgsearch>");
-+      const char* begin = strstr(aux, "<epgsearch>");
-+      const char* end = strstr(aux, "</epgsearch>");
-       if (begin && end)
-       {
-          if (begin == aux) strcpy(tmpaux, ""); else strn0cpy(tmpaux, aux, begin-aux+1);