*
  *   Copyright (C) International Business Machines  Corp., 2002,2005
  *   Author(s): Steve French (sfrench@us.ibm.com)
- *
+ *   Jeremy Allison (jra@samba.org) 2006.
+ *    
  *   This 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
 
        /* No user interrupts in wait - wreaks havoc with performance */
        if(timeout != MAX_SCHEDULE_TIMEOUT) {
-               timeout += jiffies;
-               wait_event(ses->server->response_q,
-                       (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
-                       (time_after(jiffies, timeout) &&
-                               time_after(jiffies, ses->server->lstrp + HZ)) ||
-                       ((ses->server->tcpStatus != CifsGood) &&
-                        (ses->server->tcpStatus != CifsNew)));
+               unsigned long curr_timeout;
+
+               for (;;) {
+                       curr_timeout = timeout + jiffies;
+                       wait_event(ses->server->response_q,
+                               (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
+                               time_after(jiffies, curr_timeout) || 
+                               ((ses->server->tcpStatus != CifsGood) &&
+                                (ses->server->tcpStatus != CifsNew)));
+
+                       if (time_after(jiffies, curr_timeout) &&
+                               (midQ->midState & MID_REQUEST_SUBMITTED) &&
+                               ((ses->server->tcpStatus == CifsGood) ||
+                                (ses->server->tcpStatus == CifsNew))) {
+
+                               unsigned long lrt;
+
+                               /* We timed out. Is the server still
+                                  sending replies ? */
+                               spin_lock(&GlobalMid_Lock);
+                               lrt = ses->server->lstrp;
+                               spin_unlock(&GlobalMid_Lock);
+
+                               /* Calculate 10 seconds past last receive time.
+                               Although we prefer not to time out if the 
+                               server is still responding - we will time
+                               out if the server takes more than 15 (or 45 
+                               or 180) seconds to respond to this request
+                               and has not responded to any request from 
+                               other threads on the client within 10 seconds */
+                               lrt += (10 * HZ);
+                               if (time_after(jiffies, lrt)) {
+                                       /* No replies for 10 seconds. */
+                                       cERROR(1,("server not responding"));
+                                       break;
+                               }
+                       } else {
+                               break;
+                       }
+               }
        } else {
                wait_event(ses->server->response_q,
                        (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
 
        /* No user interrupts in wait - wreaks havoc with performance */
        if(timeout != MAX_SCHEDULE_TIMEOUT) {
-               timeout += jiffies;
-               /* although we prefer not to time out if the server is still
-               responding - we will time out if the server takes
-               more than 15 (or 45 or 180) seconds to respond to this request
-               and has not responded to any request from other threads
-               on this client within a second (note that it is not worth
-               grabbing the GlobalMid_Lock and slowing things down in this
-               wait event to more accurately check the lstrsp field on some 
-               arch since we are already in an error path that will retry */
-               wait_event(ses->server->response_q,
-                       (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
-                       (time_after(jiffies, timeout) &&
-                               time_after(jiffies, ses->server->lstrp + HZ)) ||
-                       ((ses->server->tcpStatus != CifsGood) &&
-                        (ses->server->tcpStatus != CifsNew)));
+               unsigned long curr_timeout;
+
+               for (;;) {
+                       curr_timeout = timeout + jiffies;
+                       wait_event(ses->server->response_q,
+                               (!(midQ->midState & MID_REQUEST_SUBMITTED)) || 
+                               time_after(jiffies, curr_timeout) || 
+                               ((ses->server->tcpStatus != CifsGood) &&
+                                (ses->server->tcpStatus != CifsNew)));
+
+                       if (time_after(jiffies, curr_timeout) &&
+                               (midQ->midState & MID_REQUEST_SUBMITTED) &&
+                               ((ses->server->tcpStatus == CifsGood) ||
+                                (ses->server->tcpStatus == CifsNew))) {
+
+                               unsigned long lrt;
+
+                               /* We timed out. Is the server still
+                                  sending replies ? */
+                               spin_lock(&GlobalMid_Lock);
+                               lrt = ses->server->lstrp;
+                               spin_unlock(&GlobalMid_Lock);
+
+                               /* Calculate 10 seconds past last receive time*/
+                               lrt += (10 * HZ);
+                               if (time_after(jiffies, lrt)) {
+                                       /* Server sent no reply in 10 seconds */
+                                       cERROR(1,("Server not responding"));
+                                       break;
+                               }
+                       } else {
+                               break;
+                       }
+               }
        } else {
                wait_event(ses->server->response_q,
                        (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||