ia64/xen-unstable

changeset 915:a7d98f67cc9d

bitkeeper revision 1.579.1.1 (3faf8294m1pdlznRlKHUgrp9IfkTeQ)

scsi_obsolete.c:
new file
scsi.c, Makefile:
Fix generic SCSI layer to support BusLogic driver
author kaf24@scramble.cl.cam.ac.uk
date Mon Nov 10 12:20:36 2003 +0000 (2003-11-10)
parents de4c92f6eff8
children d8950052b29f
files .rootkeys xen/drivers/scsi/Makefile xen/drivers/scsi/scsi.c xen/drivers/scsi/scsi_obsolete.c
line diff
     1.1 --- a/.rootkeys	Mon Nov 10 09:52:17 2003 +0000
     1.2 +++ b/.rootkeys	Mon Nov 10 12:20:36 2003 +0000
     1.3 @@ -409,6 +409,7 @@ 3ddb79bepDvUltYDsInaUsH9lII9Sw xen/drive
     1.4  3ddb79berPStE_-ILQHgcl1BLDLywA xen/drivers/scsi/scsi_lib.c
     1.5  3ddb79beRXjB7_nNUbJMIRyjDmeByQ xen/drivers/scsi/scsi_merge.c
     1.6  3e56412a_O2cnz-e36volrKvofGe-Q xen/drivers/scsi/scsi_module.c.inc
     1.7 +3faf8290uGugKdeePovsS2MCkm6NYw xen/drivers/scsi/scsi_obsolete.c
     1.8  3ddb79beQgG_st0eBZUX8AQI7kBkHA xen/drivers/scsi/scsi_obsolete.h
     1.9  3ddb79beK65cNRldY0CFGXjZ3-A74Q xen/drivers/scsi/scsi_proc.c
    1.10  3ddb79beeIuwGDE0Ldl8wy6mt86Bag xen/drivers/scsi/scsi_queue.c
     2.1 --- a/xen/drivers/scsi/Makefile	Mon Nov 10 09:52:17 2003 +0000
     2.2 +++ b/xen/drivers/scsi/Makefile	Mon Nov 10 12:20:36 2003 +0000
     2.3 @@ -4,9 +4,9 @@ include $(BASEDIR)/Rules.mk
     2.4  # naive OBJS rule gets link order wrong
     2.5  SCSI_OBJS := scsi.o hosts.o scsicam.o scsi_dma.o scsi_error.o
     2.6  SCSI_OBJS += scsi_ioctl.o scsi_lib.o scsi_merge.o scsi_proc.o 
     2.7 -SCSI_OBJS += scsi_queue.o scsi_scan.o scsi_syms.o constants.o 
     2.8 -SCSI_OBJS += sd.o aacraid/aacraid.o aic7xxx/aic7xxx.o megaraid.o
     2.9 -SCSI_OBJS += BusLogic.o
    2.10 +SCSI_OBJS += scsi_queue.o scsi_scan.o scsi_syms.o scsi_obsolete.o
    2.11 +SCSI_OBJS += constants.o sd.o aacraid/aacraid.o aic7xxx/aic7xxx.o
    2.12 +SCSI_OBJS += megaraid.o BusLogic.o
    2.13  
    2.14  default: $(OBJS)
    2.15  	$(MAKE) -C aacraid
     3.1 --- a/xen/drivers/scsi/scsi.c	Mon Nov 10 09:52:17 2003 +0000
     3.2 +++ b/xen/drivers/scsi/scsi.c	Mon Nov 10 12:20:36 2003 +0000
     3.3 @@ -153,7 +153,6 @@ const char *const scsi_device_types[MAX_
     3.4  extern void scsi_times_out(Scsi_Cmnd * SCpnt);
     3.5  void scsi_build_commandblocks(Scsi_Device * SDpnt);
     3.6  
     3.7 -#if 0
     3.8  /*
     3.9   * These are the interface to the old error handling code.  It should go away
    3.10   * someday soon.
    3.11 @@ -161,7 +160,6 @@ void scsi_build_commandblocks(Scsi_Devic
    3.12  extern void scsi_old_done(Scsi_Cmnd * SCpnt);
    3.13  extern void scsi_old_times_out(Scsi_Cmnd * SCpnt);
    3.14  extern int scsi_old_reset(Scsi_Cmnd *SCpnt, unsigned int flag);
    3.15 -#endif
    3.16  
    3.17  /* 
    3.18   * Private interface into the new error handling code.
    3.19 @@ -696,10 +694,8 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
    3.20      if (host->hostt->use_new_eh_code) {
    3.21          scsi_add_timer(SCpnt, SCpnt->timeout_per_command, scsi_times_out);
    3.22      } else {
    3.23 -#if 0
    3.24          scsi_add_timer(SCpnt, SCpnt->timeout_per_command,
    3.25                         scsi_old_times_out);
    3.26 -#endif
    3.27      }
    3.28      
    3.29      /*
    3.30 @@ -751,7 +747,6 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
    3.31               * Before we queue this command, check if the command
    3.32               * length exceeds what the host adapter can handle.
    3.33               */
    3.34 -#if 0
    3.35              if (CDB_SIZE(SCpnt) <= SCpnt->host->max_cmd_len) {
    3.36                  spin_lock_irqsave(&io_request_lock, flags);
    3.37                  host->hostt->queuecommand(SCpnt, scsi_old_done);
    3.38 @@ -765,7 +760,6 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
    3.39                  spin_unlock_irqrestore(&io_request_lock, flags);
    3.40                  rtn = 1;
    3.41              }
    3.42 -#endif
    3.43              
    3.44          }
    3.45      } else {
    3.46 @@ -790,9 +784,7 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
    3.47          if (host->hostt->use_new_eh_code) {
    3.48              scsi_done(SCpnt);
    3.49          } else {
    3.50 -#if 0
    3.51              scsi_old_done(SCpnt);
    3.52 -#endif
    3.53          }
    3.54          spin_unlock_irqrestore(&io_request_lock, flags);
    3.55      }
    3.56 @@ -2951,13 +2943,11 @@ scsi_reset_provider(Scsi_Device *dev, in
    3.57  	if (dev->host->hostt->use_new_eh_code) {
    3.58  		rtn = scsi_new_reset(SCpnt, flag);
    3.59  	} else {
    3.60 -#if 0
    3.61  		unsigned long flags;
    3.62  
    3.63  		spin_lock_irqsave(&io_request_lock, flags);
    3.64  		rtn = scsi_old_reset(SCpnt, flag);
    3.65  		spin_unlock_irqrestore(&io_request_lock, flags);
    3.66 -#endif
    3.67                  rtn= 0; 
    3.68  	}
    3.69  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/drivers/scsi/scsi_obsolete.c	Mon Nov 10 12:20:36 2003 +0000
     4.3 @@ -0,0 +1,1162 @@
     4.4 +/*
     4.5 + *  scsi_obsolete.c Copyright (C) 1992 Drew Eckhardt
     4.6 + *         Copyright (C) 1993, 1994, 1995 Eric Youngdale
     4.7 + *
     4.8 + *  generic mid-level SCSI driver
     4.9 + *      Initial versions: Drew Eckhardt
    4.10 + *      Subsequent revisions: Eric Youngdale
    4.11 + *
    4.12 + *  <drew@colorado.edu>
    4.13 + *
    4.14 + *  Bug correction thanks go to :
    4.15 + *      Rik Faith <faith@cs.unc.edu>
    4.16 + *      Tommy Thorn <tthorn>
    4.17 + *      Thomas Wuensche <tw@fgb1.fgb.mw.tu-muenchen.de>
    4.18 + *
    4.19 + *  Modified by Eric Youngdale eric@andante.org to
    4.20 + *  add scatter-gather, multiple outstanding request, and other
    4.21 + *  enhancements.
    4.22 + *
    4.23 + *  Native multichannel, wide scsi, /proc/scsi and hot plugging
    4.24 + *  support added by Michael Neuffer <mike@i-connect.net>
    4.25 + *
    4.26 + *  Major improvements to the timeout, abort, and reset processing,
    4.27 + *  as well as performance modifications for large queue depths by
    4.28 + *  Leonard N. Zubkoff <lnz@dandelion.com>
    4.29 + *
    4.30 + *  Improved compatibility with 2.0 behaviour by Manfred Spraul
    4.31 + *  <masp0008@stud.uni-sb.de>
    4.32 + */
    4.33 +
    4.34 +/*
    4.35 + *#########################################################################
    4.36 + *#########################################################################
    4.37 + *#########################################################################
    4.38 + *#########################################################################
    4.39 + *              NOTE - NOTE - NOTE - NOTE - NOTE - NOTE - NOTE
    4.40 + *
    4.41 + *#########################################################################
    4.42 + *#########################################################################
    4.43 + *#########################################################################
    4.44 + *#########################################################################
    4.45 + *
    4.46 + * This file contains the 'old' scsi error handling.  It is only present
    4.47 + * while the new error handling code is being debugged, and while the low
    4.48 + * level drivers are being converted to use the new code.  Once the last
    4.49 + * driver uses the new code this *ENTIRE* file will be nuked.
    4.50 + */
    4.51 +
    4.52 +#define __NO_VERSION__
    4.53 +#include <linux/module.h>
    4.54 +
    4.55 +#include <linux/sched.h>
    4.56 +#include <linux/timer.h>
    4.57 +#include <linux/string.h>
    4.58 +#include <linux/slab.h>
    4.59 +#include <linux/ioport.h>
    4.60 +#include <linux/kernel.h>
    4.61 +/*#include <linux/stat.h>*/
    4.62 +#include <linux/blk.h>
    4.63 +#include <linux/interrupt.h>
    4.64 +#include <linux/delay.h>
    4.65 +
    4.66 +#include <asm/system.h>
    4.67 +#include <asm/irq.h>
    4.68 +#include <asm/dma.h>
    4.69 +
    4.70 +#include "scsi.h"
    4.71 +#include "hosts.h"
    4.72 +#include "constants.h"
    4.73 +
    4.74 +#undef USE_STATIC_SCSI_MEMORY
    4.75 +
    4.76 +/*
    4.77 +   static const char RCSid[] = "$Header: /mnt/ide/home/eric/CVSROOT/linux/drivers/scsi/scsi_obsolete.c,v 1.1 1997/05/18 23:27:21 eric Exp $";
    4.78 + */
    4.79 +
    4.80 +
    4.81 +#define INTERNAL_ERROR (panic ("Internal error in file %s, line %d.\n", __FILE__, __LINE__))
    4.82 +
    4.83 +
    4.84 +static int scsi_abort(Scsi_Cmnd *, int code);
    4.85 +static int scsi_reset(Scsi_Cmnd *, unsigned int);
    4.86 +
    4.87 +extern void scsi_old_done(Scsi_Cmnd * SCpnt);
    4.88 +int update_timeout(Scsi_Cmnd *, int);
    4.89 +extern void scsi_old_times_out(Scsi_Cmnd * SCpnt);
    4.90 +
    4.91 +extern int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt);
    4.92 +
    4.93 +#define SCSI_BLOCK(HOST) (HOST->can_queue && HOST->host_busy >= HOST->can_queue)
    4.94 +
    4.95 +static unsigned char generic_sense[6] =
    4.96 +{REQUEST_SENSE, 0, 0, 0, 255, 0};
    4.97 +
    4.98 +/*
    4.99 + *  This is the number  of clock ticks we should wait before we time out
   4.100 + *  and abort the command.  This is for  where the scsi.c module generates
   4.101 + *  the command, not where it originates from a higher level, in which
   4.102 + *  case the timeout is specified there.
   4.103 + *
   4.104 + *  ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT
   4.105 + *  respectively.
   4.106 + */
   4.107 +
   4.108 +#ifdef DEBUG_TIMEOUT
   4.109 +static void scsi_dump_status(void);
   4.110 +#endif
   4.111 +
   4.112 +
   4.113 +#ifdef DEBUG
   4.114 +#define SCSI_TIMEOUT (5*HZ)
   4.115 +#else
   4.116 +#define SCSI_TIMEOUT (2*HZ)
   4.117 +#endif
   4.118 +
   4.119 +#ifdef DEBUG
   4.120 +#define SENSE_TIMEOUT SCSI_TIMEOUT
   4.121 +#define ABORT_TIMEOUT SCSI_TIMEOUT
   4.122 +#define RESET_TIMEOUT SCSI_TIMEOUT
   4.123 +#else
   4.124 +#define SENSE_TIMEOUT (5*HZ/10)
   4.125 +#define RESET_TIMEOUT (5*HZ/10)
   4.126 +#define ABORT_TIMEOUT (5*HZ/10)
   4.127 +#endif
   4.128 +
   4.129 +
   4.130 +/* Do not call reset on error if we just did a reset within 15 sec. */
   4.131 +#define MIN_RESET_PERIOD (15*HZ)
   4.132 +
   4.133 +
   4.134 +
   4.135 +/*
   4.136 + *  Flag bits for the internal_timeout array
   4.137 + */
   4.138 +#define IN_ABORT  1
   4.139 +#define IN_RESET  2
   4.140 +#define IN_RESET2 4
   4.141 +#define IN_RESET3 8
   4.142 +
   4.143 +/*
   4.144 + * This is our time out function, called when the timer expires for a
   4.145 + * given host adapter.  It will attempt to abort the currently executing
   4.146 + * command, that failing perform a kernel panic.
   4.147 + */
   4.148 +
   4.149 +void scsi_old_times_out(Scsi_Cmnd * SCpnt)
   4.150 +{
   4.151 +	unsigned long flags;
   4.152 +
   4.153 +	spin_lock_irqsave(&io_request_lock, flags);
   4.154 +
   4.155 +	/* Set the serial_number_at_timeout to the current serial_number */
   4.156 +	SCpnt->serial_number_at_timeout = SCpnt->serial_number;
   4.157 +
   4.158 +	switch (SCpnt->internal_timeout & (IN_ABORT | IN_RESET | IN_RESET2 | IN_RESET3)) {
   4.159 +	case NORMAL_TIMEOUT:
   4.160 +		{
   4.161 +#ifdef DEBUG_TIMEOUT
   4.162 +			scsi_dump_status();
   4.163 +#endif
   4.164 +		}
   4.165 +
   4.166 +		if (!scsi_abort(SCpnt, DID_TIME_OUT))
   4.167 +			break;
   4.168 +	case IN_ABORT:
   4.169 +		printk("SCSI host %d abort (pid %ld) timed out - resetting\n",
   4.170 +		       SCpnt->host->host_no, SCpnt->pid);
   4.171 +		if (!scsi_reset(SCpnt, SCSI_RESET_ASYNCHRONOUS))
   4.172 +			break;
   4.173 +	case IN_RESET:
   4.174 +	case (IN_ABORT | IN_RESET):
   4.175 +		/* This might be controversial, but if there is a bus hang,
   4.176 +		 * you might conceivably want the machine up and running
   4.177 +		 * esp if you have an ide disk.
   4.178 +		 */
   4.179 +		printk("SCSI host %d channel %d reset (pid %ld) timed out - "
   4.180 +		       "trying harder\n",
   4.181 +		       SCpnt->host->host_no, SCpnt->channel, SCpnt->pid);
   4.182 +		SCpnt->internal_timeout &= ~IN_RESET;
   4.183 +		SCpnt->internal_timeout |= IN_RESET2;
   4.184 +		scsi_reset(SCpnt,
   4.185 +		 SCSI_RESET_ASYNCHRONOUS | SCSI_RESET_SUGGEST_BUS_RESET);
   4.186 +		break;
   4.187 +	case IN_RESET2:
   4.188 +	case (IN_ABORT | IN_RESET2):
   4.189 +		/* Obviously the bus reset didn't work.
   4.190 +		 * Let's try even harder and call for an HBA reset.
   4.191 +		 * Maybe the HBA itself crashed and this will shake it loose.
   4.192 +		 */
   4.193 +		printk("SCSI host %d reset (pid %ld) timed out - trying to shake it loose\n",
   4.194 +		       SCpnt->host->host_no, SCpnt->pid);
   4.195 +		SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2);
   4.196 +		SCpnt->internal_timeout |= IN_RESET3;
   4.197 +		scsi_reset(SCpnt,
   4.198 +		SCSI_RESET_ASYNCHRONOUS | SCSI_RESET_SUGGEST_HOST_RESET);
   4.199 +		break;
   4.200 +
   4.201 +	default:
   4.202 +		printk("SCSI host %d reset (pid %ld) timed out again -\n",
   4.203 +		       SCpnt->host->host_no, SCpnt->pid);
   4.204 +		printk("probably an unrecoverable SCSI bus or device hang.\n");
   4.205 +		break;
   4.206 +
   4.207 +	}
   4.208 +	spin_unlock_irqrestore(&io_request_lock, flags);
   4.209 +
   4.210 +}
   4.211 +
   4.212 +/*
   4.213 + *  From what I can find in scsi_obsolete.c, this function is only called
   4.214 + *  by scsi_old_done and scsi_reset.  Both of these functions run with the
   4.215 + *  io_request_lock already held, so we need do nothing here about grabbing
   4.216 + *  any locks.
   4.217 + */
   4.218 +static void scsi_request_sense(Scsi_Cmnd * SCpnt)
   4.219 +{
   4.220 +	SCpnt->flags |= WAS_SENSE | ASKED_FOR_SENSE;
   4.221 +	update_timeout(SCpnt, SENSE_TIMEOUT);
   4.222 +
   4.223 +
   4.224 +	memcpy((void *) SCpnt->cmnd, (void *) generic_sense,
   4.225 +	       sizeof(generic_sense));
   4.226 +	memset((void *) SCpnt->sense_buffer, 0,
   4.227 +	       sizeof(SCpnt->sense_buffer));
   4.228 +
   4.229 +	if (SCpnt->device->scsi_level <= SCSI_2)
   4.230 +		SCpnt->cmnd[1] = SCpnt->lun << 5;
   4.231 +	SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer);
   4.232 +
   4.233 +	SCpnt->request_buffer = &SCpnt->sense_buffer;
   4.234 +	SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
   4.235 +	SCpnt->use_sg = 0;
   4.236 +	SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
   4.237 +	SCpnt->result = 0;
   4.238 +	SCpnt->sc_data_direction = SCSI_DATA_READ;
   4.239 +
   4.240 +        /*
   4.241 +         * Ugly, ugly.  The newer interfaces all assume that the lock
   4.242 +         * isn't held.  Mustn't disappoint, or we deadlock the system.
   4.243 +         */
   4.244 +        spin_unlock_irq(&io_request_lock);
   4.245 +	scsi_dispatch_cmd(SCpnt);
   4.246 +        spin_lock_irq(&io_request_lock);
   4.247 +}
   4.248 +
   4.249 +
   4.250 +
   4.251 +
   4.252 +static int check_sense(Scsi_Cmnd * SCpnt)
   4.253 +{
   4.254 +	/* If there is no sense information, request it.  If we have already
   4.255 +	 * requested it, there is no point in asking again - the firmware must
   4.256 +	 * be confused.
   4.257 +	 */
   4.258 +	if (((SCpnt->sense_buffer[0] & 0x70) >> 4) != 7) {
   4.259 +		if (!(SCpnt->flags & ASKED_FOR_SENSE))
   4.260 +			return SUGGEST_SENSE;
   4.261 +		else
   4.262 +			return SUGGEST_RETRY;
   4.263 +	}
   4.264 +	SCpnt->flags &= ~ASKED_FOR_SENSE;
   4.265 +
   4.266 +#ifdef DEBUG_INIT
   4.267 +	printk("scsi%d, channel%d : ", SCpnt->host->host_no, SCpnt->channel);
   4.268 +	print_sense("", SCpnt);
   4.269 +	printk("\n");
   4.270 +#endif
   4.271 +	if (SCpnt->sense_buffer[2] & 0xe0)
   4.272 +		return SUGGEST_ABORT;
   4.273 +
   4.274 +	switch (SCpnt->sense_buffer[2] & 0xf) {
   4.275 +	case NO_SENSE:
   4.276 +		return 0;
   4.277 +	case RECOVERED_ERROR:
   4.278 +		return SUGGEST_IS_OK;
   4.279 +
   4.280 +	case ABORTED_COMMAND:
   4.281 +		return SUGGEST_RETRY;
   4.282 +	case NOT_READY:
   4.283 +	case UNIT_ATTENTION:
   4.284 +		/*
   4.285 +		 * If we are expecting a CC/UA because of a bus reset that we
   4.286 +		 * performed, treat this just as a retry.  Otherwise this is
   4.287 +		 * information that we should pass up to the upper-level driver
   4.288 +		 * so that we can deal with it there.
   4.289 +		 */
   4.290 +		if (SCpnt->device->expecting_cc_ua) {
   4.291 +			SCpnt->device->expecting_cc_ua = 0;
   4.292 +			return SUGGEST_RETRY;
   4.293 +		}
   4.294 +		return SUGGEST_ABORT;
   4.295 +
   4.296 +		/* these three are not supported */
   4.297 +	case COPY_ABORTED:
   4.298 +	case VOLUME_OVERFLOW:
   4.299 +	case MISCOMPARE:
   4.300 +
   4.301 +	case MEDIUM_ERROR:
   4.302 +		return SUGGEST_REMAP;
   4.303 +	case BLANK_CHECK:
   4.304 +	case DATA_PROTECT:
   4.305 +	case HARDWARE_ERROR:
   4.306 +	case ILLEGAL_REQUEST:
   4.307 +	default:
   4.308 +		return SUGGEST_ABORT;
   4.309 +	}
   4.310 +}
   4.311 +
   4.312 +/* This function is the mid-level interrupt routine, which decides how
   4.313 + *  to handle error conditions.  Each invocation of this function must
   4.314 + *  do one and *only* one of the following:
   4.315 + *
   4.316 + *  (1) Call last_cmnd[host].done.  This is done for fatal errors and
   4.317 + *      normal completion, and indicates that the handling for this
   4.318 + *      request is complete.
   4.319 + *  (2) Call internal_cmnd to requeue the command.  This will result in
   4.320 + *      scsi_done being called again when the retry is complete.
   4.321 + *  (3) Call scsi_request_sense.  This asks the host adapter/drive for
   4.322 + *      more information about the error condition.  When the information
   4.323 + *      is available, scsi_done will be called again.
   4.324 + *  (4) Call reset().  This is sort of a last resort, and the idea is that
   4.325 + *      this may kick things loose and get the drive working again.  reset()
   4.326 + *      automatically calls scsi_request_sense, and thus scsi_done will be
   4.327 + *      called again once the reset is complete.
   4.328 + *
   4.329 + *      If none of the above actions are taken, the drive in question
   4.330 + *      will hang. If more than one of the above actions are taken by
   4.331 + *      scsi_done, then unpredictable behavior will result.
   4.332 + */
   4.333 +void scsi_old_done(Scsi_Cmnd * SCpnt)
   4.334 +{
   4.335 +	int status = 0;
   4.336 +	int exit = 0;
   4.337 +	int checked;
   4.338 +	int oldto;
   4.339 +	struct Scsi_Host *host = SCpnt->host;
   4.340 +        Scsi_Device * device = SCpnt->device;
   4.341 +	int result = SCpnt->result;
   4.342 +	SCpnt->serial_number = 0;
   4.343 +	SCpnt->serial_number_at_timeout = 0;
   4.344 +	oldto = update_timeout(SCpnt, 0);
   4.345 +
   4.346 +#ifdef DEBUG_TIMEOUT
   4.347 +	if (result)
   4.348 +		printk("Non-zero result in scsi_done %x %d:%d\n",
   4.349 +		       result, SCpnt->target, SCpnt->lun);
   4.350 +#endif
   4.351 +
   4.352 +	/* If we requested an abort, (and we got it) then fix up the return
   4.353 +	 *  status to say why
   4.354 +	 */
   4.355 +	if (host_byte(result) == DID_ABORT && SCpnt->abort_reason)
   4.356 +		SCpnt->result = result = (result & 0xff00ffff) |
   4.357 +		    (SCpnt->abort_reason << 16);
   4.358 +
   4.359 +
   4.360 +#define CMD_FINISHED 0
   4.361 +#define MAYREDO  1
   4.362 +#define REDO     3
   4.363 +#define PENDING  4
   4.364 +
   4.365 +#ifdef DEBUG
   4.366 +	printk("In scsi_done(host = %d, result = %06x)\n", host->host_no, result);
   4.367 +#endif
   4.368 +
   4.369 +	if (SCpnt->flags & SYNC_RESET) {
   4.370 +		/*
   4.371 +		   * The behaviou of scsi_reset(SYNC) was changed in 2.1.? .
   4.372 +		   * The scsi mid-layer does a REDO after every sync reset, the driver
   4.373 +		   * must not do that any more. In order to prevent old drivers from
   4.374 +		   * crashing, all scsi_done() calls during sync resets are ignored.
   4.375 +		 */
   4.376 +		printk("scsi%d: device driver called scsi_done() "
   4.377 +		       "for a synchronous reset.\n", SCpnt->host->host_no);
   4.378 +		return;
   4.379 +	}
   4.380 +	if (SCpnt->flags & WAS_SENSE) {
   4.381 +		SCpnt->use_sg = SCpnt->old_use_sg;
   4.382 +		SCpnt->cmd_len = SCpnt->old_cmd_len;
   4.383 +		SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;
   4.384 +		SCpnt->underflow = SCpnt->old_underflow;
   4.385 +	}
   4.386 +	switch (host_byte(result)) {
   4.387 +	case DID_OK:
   4.388 +		if (status_byte(result) && (SCpnt->flags & WAS_SENSE))
   4.389 +			/* Failed to obtain sense information */
   4.390 +		{
   4.391 +			SCpnt->flags &= ~WAS_SENSE;
   4.392 +#if 0				/* This cannot possibly be correct. */
   4.393 +			SCpnt->internal_timeout &= ~SENSE_TIMEOUT;
   4.394 +#endif
   4.395 +
   4.396 +			if (!(SCpnt->flags & WAS_RESET)) {
   4.397 +				printk("scsi%d : channel %d target %d lun %d request sense"
   4.398 +				       " failed, performing reset.\n",
   4.399 +				       SCpnt->host->host_no, SCpnt->channel, SCpnt->target,
   4.400 +				       SCpnt->lun);
   4.401 +				scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS);
   4.402 +				status = REDO;
   4.403 +				break;
   4.404 +			} else {
   4.405 +				exit = (DRIVER_HARD | SUGGEST_ABORT);
   4.406 +				status = CMD_FINISHED;
   4.407 +			}
   4.408 +		} else
   4.409 +			switch (msg_byte(result)) {
   4.410 +			case COMMAND_COMPLETE:
   4.411 +				switch (status_byte(result)) {
   4.412 +				case GOOD:
   4.413 +					if (SCpnt->flags & WAS_SENSE) {
   4.414 +#ifdef DEBUG
   4.415 +						printk("In scsi_done, GOOD status, COMMAND COMPLETE, "
   4.416 +						       "parsing sense information.\n");
   4.417 +#endif
   4.418 +						SCpnt->flags &= ~WAS_SENSE;
   4.419 +#if 0				/* This cannot possibly be correct. */
   4.420 +						SCpnt->internal_timeout &= ~SENSE_TIMEOUT;
   4.421 +#endif
   4.422 +
   4.423 +						switch (checked = check_sense(SCpnt)) {
   4.424 +						case SUGGEST_SENSE:
   4.425 +						case 0:
   4.426 +#ifdef DEBUG
   4.427 +							printk("NO SENSE.  status = REDO\n");
   4.428 +#endif
   4.429 +							update_timeout(SCpnt, oldto);
   4.430 +							status = REDO;
   4.431 +							break;
   4.432 +						case SUGGEST_IS_OK:
   4.433 +							break;
   4.434 +						case SUGGEST_REMAP:
   4.435 +#ifdef DEBUG
   4.436 +							printk("SENSE SUGGEST REMAP - status = CMD_FINISHED\n");
   4.437 +#endif
   4.438 +							status = CMD_FINISHED;
   4.439 +							exit = DRIVER_SENSE | SUGGEST_ABORT;
   4.440 +							break;
   4.441 +						case SUGGEST_RETRY:
   4.442 +#ifdef DEBUG
   4.443 +							printk("SENSE SUGGEST RETRY - status = MAYREDO\n");
   4.444 +#endif
   4.445 +							status = MAYREDO;
   4.446 +							exit = DRIVER_SENSE | SUGGEST_RETRY;
   4.447 +							break;
   4.448 +						case SUGGEST_ABORT:
   4.449 +#ifdef DEBUG
   4.450 +							printk("SENSE SUGGEST ABORT - status = CMD_FINISHED");
   4.451 +#endif
   4.452 +							status = CMD_FINISHED;
   4.453 +							exit = DRIVER_SENSE | SUGGEST_ABORT;
   4.454 +							break;
   4.455 +						default:
   4.456 +							printk("Internal error %s %d \n", __FILE__,
   4.457 +							       __LINE__);
   4.458 +						}
   4.459 +					}
   4.460 +					/* end WAS_SENSE */
   4.461 +					else {
   4.462 +#ifdef DEBUG
   4.463 +						printk("COMMAND COMPLETE message returned, "
   4.464 +						       "status = CMD_FINISHED. \n");
   4.465 +#endif
   4.466 +						exit = DRIVER_OK;
   4.467 +						status = CMD_FINISHED;
   4.468 +					}
   4.469 +					break;
   4.470 +
   4.471 +				case CHECK_CONDITION:
   4.472 +				case COMMAND_TERMINATED:
   4.473 +					switch (check_sense(SCpnt)) {
   4.474 +					case 0:
   4.475 +						update_timeout(SCpnt, oldto);
   4.476 +						status = REDO;
   4.477 +						break;
   4.478 +					case SUGGEST_REMAP:
   4.479 +						status = CMD_FINISHED;
   4.480 +						exit = DRIVER_SENSE | SUGGEST_ABORT;
   4.481 +						break;
   4.482 +					case SUGGEST_RETRY:
   4.483 +						status = MAYREDO;
   4.484 +						exit = DRIVER_SENSE | SUGGEST_RETRY;
   4.485 +						break;
   4.486 +					case SUGGEST_ABORT:
   4.487 +						status = CMD_FINISHED;
   4.488 +						exit = DRIVER_SENSE | SUGGEST_ABORT;
   4.489 +						break;
   4.490 +					case SUGGEST_SENSE:
   4.491 +						scsi_request_sense(SCpnt);
   4.492 +						status = PENDING;
   4.493 +						break;
   4.494 +					}
   4.495 +					break;
   4.496 +
   4.497 +				case CONDITION_GOOD:
   4.498 +				case INTERMEDIATE_GOOD:
   4.499 +				case INTERMEDIATE_C_GOOD:
   4.500 +					break;
   4.501 +
   4.502 +				case BUSY:
   4.503 +				case QUEUE_FULL:
   4.504 +					update_timeout(SCpnt, oldto);
   4.505 +					status = REDO;
   4.506 +					break;
   4.507 +
   4.508 +				case RESERVATION_CONFLICT:
   4.509 +					/*
   4.510 +					 * Most HAs will return an error for
   4.511 +					 * this, so usually reservation
   4.512 +					 * conflicts will  be processed under
   4.513 +					 * DID_ERROR code
   4.514 +					 */
   4.515 +					printk("scsi%d (%d,%d,%d) : RESERVATION CONFLICT\n", 
   4.516 +					       SCpnt->host->host_no, SCpnt->channel,
   4.517 +					       SCpnt->device->id, SCpnt->device->lun);
   4.518 +					status = CMD_FINISHED; /* returns I/O error */
   4.519 +					break;
   4.520 +                                        
   4.521 +				default:
   4.522 +					printk("Internal error %s %d \n"
   4.523 +					 "status byte = %d \n", __FILE__,
   4.524 +					  __LINE__, status_byte(result));
   4.525 +
   4.526 +				}
   4.527 +				break;
   4.528 +			default:
   4.529 +				panic("scsi: unsupported message byte %d received\n",
   4.530 +				      msg_byte(result));
   4.531 +			}
   4.532 +		break;
   4.533 +	case DID_TIME_OUT:
   4.534 +#ifdef DEBUG
   4.535 +		printk("Host returned DID_TIME_OUT - ");
   4.536 +#endif
   4.537 +
   4.538 +		if (SCpnt->flags & WAS_TIMEDOUT) {
   4.539 +#ifdef DEBUG
   4.540 +			printk("Aborting\n");
   4.541 +#endif
   4.542 +			/*
   4.543 +			   Allow TEST_UNIT_READY and INQUIRY commands to timeout early
   4.544 +			   without causing resets.  All other commands should be retried.
   4.545 +			 */
   4.546 +			if (SCpnt->cmnd[0] != TEST_UNIT_READY &&
   4.547 +			    SCpnt->cmnd[0] != INQUIRY)
   4.548 +				status = MAYREDO;
   4.549 +			exit = (DRIVER_TIMEOUT | SUGGEST_ABORT);
   4.550 +		} else {
   4.551 +#ifdef DEBUG
   4.552 +			printk("Retrying.\n");
   4.553 +#endif
   4.554 +			SCpnt->flags |= WAS_TIMEDOUT;
   4.555 +			SCpnt->internal_timeout &= ~IN_ABORT;
   4.556 +			status = REDO;
   4.557 +		}
   4.558 +		break;
   4.559 +	case DID_BUS_BUSY:
   4.560 +	case DID_PARITY:
   4.561 +		status = REDO;
   4.562 +		break;
   4.563 +	case DID_NO_CONNECT:
   4.564 +#ifdef DEBUG
   4.565 +		printk("Couldn't connect.\n");
   4.566 +#endif
   4.567 +		exit = (DRIVER_HARD | SUGGEST_ABORT);
   4.568 +		break;
   4.569 +	case DID_ERROR:
   4.570 +		if (msg_byte(result) == COMMAND_COMPLETE &&
   4.571 +		    status_byte(result) == RESERVATION_CONFLICT) {
   4.572 +			printk("scsi%d (%d,%d,%d) : RESERVATION CONFLICT\n", 
   4.573 +			       SCpnt->host->host_no, SCpnt->channel,
   4.574 +			       SCpnt->device->id, SCpnt->device->lun);
   4.575 +			status = CMD_FINISHED; /* returns I/O error */
   4.576 +			break;
   4.577 +		}
   4.578 +		status = MAYREDO;
   4.579 +		exit = (DRIVER_HARD | SUGGEST_ABORT);
   4.580 +		break;
   4.581 +	case DID_BAD_TARGET:
   4.582 +	case DID_ABORT:
   4.583 +		exit = (DRIVER_INVALID | SUGGEST_ABORT);
   4.584 +		break;
   4.585 +	case DID_RESET:
   4.586 +		if (SCpnt->flags & IS_RESETTING) {
   4.587 +			SCpnt->flags &= ~IS_RESETTING;
   4.588 +			status = REDO;
   4.589 +			break;
   4.590 +		}
   4.591 +		if (msg_byte(result) == GOOD &&
   4.592 +		    status_byte(result) == CHECK_CONDITION) {
   4.593 +			switch (check_sense(SCpnt)) {
   4.594 +			case 0:
   4.595 +				update_timeout(SCpnt, oldto);
   4.596 +				status = REDO;
   4.597 +				break;
   4.598 +			case SUGGEST_REMAP:
   4.599 +			case SUGGEST_RETRY:
   4.600 +				status = MAYREDO;
   4.601 +				exit = DRIVER_SENSE | SUGGEST_RETRY;
   4.602 +				break;
   4.603 +			case SUGGEST_ABORT:
   4.604 +				status = CMD_FINISHED;
   4.605 +				exit = DRIVER_SENSE | SUGGEST_ABORT;
   4.606 +				break;
   4.607 +			case SUGGEST_SENSE:
   4.608 +				scsi_request_sense(SCpnt);
   4.609 +				status = PENDING;
   4.610 +				break;
   4.611 +			}
   4.612 +		} else {
   4.613 +			status = REDO;
   4.614 +			exit = SUGGEST_RETRY;
   4.615 +		}
   4.616 +		break;
   4.617 +	default:
   4.618 +		exit = (DRIVER_ERROR | SUGGEST_DIE);
   4.619 +	}
   4.620 +
   4.621 +	switch (status) {
   4.622 +	case CMD_FINISHED:
   4.623 +	case PENDING:
   4.624 +		break;
   4.625 +	case MAYREDO:
   4.626 +#ifdef DEBUG
   4.627 +		printk("In MAYREDO, allowing %d retries, have %d\n",
   4.628 +		       SCpnt->allowed, SCpnt->retries);
   4.629 +#endif
   4.630 +		if ((++SCpnt->retries) < SCpnt->allowed) {
   4.631 +			if ((SCpnt->retries >= (SCpnt->allowed >> 1))
   4.632 +			    && !(SCpnt->host->resetting && time_before(jiffies, SCpnt->host->last_reset + MIN_RESET_PERIOD))
   4.633 +			    && !(SCpnt->flags & WAS_RESET)) {
   4.634 +				printk("scsi%d channel %d : resetting for second half of retries.\n",
   4.635 +				   SCpnt->host->host_no, SCpnt->channel);
   4.636 +				scsi_reset(SCpnt, SCSI_RESET_SYNCHRONOUS);
   4.637 +				/* fall through to REDO */
   4.638 +			}
   4.639 +		} else {
   4.640 +			status = CMD_FINISHED;
   4.641 +			break;
   4.642 +		}
   4.643 +		/* fall through to REDO */
   4.644 +
   4.645 +	case REDO:
   4.646 +
   4.647 +		if (SCpnt->flags & WAS_SENSE)
   4.648 +			scsi_request_sense(SCpnt);
   4.649 +		else {
   4.650 +			memcpy((void *) SCpnt->cmnd,
   4.651 +			       (void *) SCpnt->data_cmnd,
   4.652 +			       sizeof(SCpnt->data_cmnd));
   4.653 +			memset((void *) SCpnt->sense_buffer, 0,
   4.654 +			       sizeof(SCpnt->sense_buffer));
   4.655 +			SCpnt->request_buffer = SCpnt->buffer;
   4.656 +			SCpnt->request_bufflen = SCpnt->bufflen;
   4.657 +			SCpnt->use_sg = SCpnt->old_use_sg;
   4.658 +			SCpnt->cmd_len = SCpnt->old_cmd_len;
   4.659 +			SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;
   4.660 +			SCpnt->underflow = SCpnt->old_underflow;
   4.661 +			SCpnt->result = 0;
   4.662 +                        /*
   4.663 +                         * Ugly, ugly.  The newer interfaces all
   4.664 +                         * assume that the lock isn't held.  Mustn't
   4.665 +                         * disappoint, or we deadlock the system.  
   4.666 +                         */
   4.667 +                        spin_unlock_irq(&io_request_lock);
   4.668 +			scsi_dispatch_cmd(SCpnt);
   4.669 +                        spin_lock_irq(&io_request_lock);
   4.670 +		}
   4.671 +		break;
   4.672 +	default:
   4.673 +		INTERNAL_ERROR;
   4.674 +	}
   4.675 +
   4.676 +	if (status == CMD_FINISHED) {
   4.677 +		Scsi_Request *SRpnt;
   4.678 +#ifdef DEBUG
   4.679 +		printk("Calling done function - at address %p\n", SCpnt->done);
   4.680 +#endif
   4.681 +		host->host_busy--;	/* Indicate that we are free */
   4.682 +                device->device_busy--;	/* Decrement device usage counter. */
   4.683 +
   4.684 +		SCpnt->result = result | ((exit & 0xff) << 24);
   4.685 +		SCpnt->use_sg = SCpnt->old_use_sg;
   4.686 +		SCpnt->cmd_len = SCpnt->old_cmd_len;
   4.687 +		SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;
   4.688 +		SCpnt->underflow = SCpnt->old_underflow;
   4.689 +                /*
   4.690 +                 * The upper layers assume the lock isn't held.  We mustn't
   4.691 +                 * disappoint them.  When the new error handling code is in
   4.692 +                 * use, the upper code is run from a bottom half handler, so
   4.693 +                 * it isn't an issue.
   4.694 +                 */
   4.695 +                spin_unlock_irq(&io_request_lock);
   4.696 +		SRpnt = SCpnt->sc_request;
   4.697 +		if( SRpnt != NULL ) {
   4.698 +			SRpnt->sr_result = SRpnt->sr_command->result;
   4.699 +			if( SRpnt->sr_result != 0 ) {
   4.700 +				memcpy(SRpnt->sr_sense_buffer,
   4.701 +				       SRpnt->sr_command->sense_buffer,
   4.702 +				       sizeof(SRpnt->sr_sense_buffer));
   4.703 +			}
   4.704 +		}
   4.705 +
   4.706 +		SCpnt->done(SCpnt);
   4.707 +                spin_lock_irq(&io_request_lock);
   4.708 +	}
   4.709 +#undef CMD_FINISHED
   4.710 +#undef REDO
   4.711 +#undef MAYREDO
   4.712 +#undef PENDING
   4.713 +}
   4.714 +
   4.715 +/*
   4.716 + * The scsi_abort function interfaces with the abort() function of the host
   4.717 + * we are aborting, and causes the current command to not complete.  The
   4.718 + * caller should deal with any error messages or status returned on the
   4.719 + * next call.
   4.720 + *
   4.721 + * This will not be called reentrantly for a given host.
   4.722 + */
   4.723 +
   4.724 +/*
   4.725 + * Since we're nice guys and specified that abort() and reset()
   4.726 + * can be non-reentrant.  The internal_timeout flags are used for
   4.727 + * this.
   4.728 + */
   4.729 +
   4.730 +
   4.731 +static int scsi_abort(Scsi_Cmnd * SCpnt, int why)
   4.732 +{
   4.733 +	int oldto;
   4.734 +	struct Scsi_Host *host = SCpnt->host;
   4.735 +
   4.736 +	while (1) {
   4.737 +
   4.738 +		/*
   4.739 +		 * Protect against races here.  If the command is done, or we are
   4.740 +		 * on a different command forget it.
   4.741 +		 */
   4.742 +		if (SCpnt->serial_number != SCpnt->serial_number_at_timeout) {
   4.743 +			return 0;
   4.744 +		}
   4.745 +		if (SCpnt->internal_timeout & IN_ABORT) {
   4.746 +			spin_unlock_irq(&io_request_lock);
   4.747 +			while (SCpnt->internal_timeout & IN_ABORT)
   4.748 +				barrier();
   4.749 +			spin_lock_irq(&io_request_lock);
   4.750 +		} else {
   4.751 +			SCpnt->internal_timeout |= IN_ABORT;
   4.752 +			oldto = update_timeout(SCpnt, ABORT_TIMEOUT);
   4.753 +
   4.754 +			if ((SCpnt->flags & IS_RESETTING) && SCpnt->device->soft_reset) {
   4.755 +				/* OK, this command must have died when we did the
   4.756 +				 *  reset.  The device itself must have lied.
   4.757 +				 */
   4.758 +				printk("Stale command on %d %d:%d appears to have died when"
   4.759 +				       " the bus was reset\n",
   4.760 +				       SCpnt->channel, SCpnt->target, SCpnt->lun);
   4.761 +			}
   4.762 +			if (!host->host_busy) {
   4.763 +				SCpnt->internal_timeout &= ~IN_ABORT;
   4.764 +				update_timeout(SCpnt, oldto);
   4.765 +				return 0;
   4.766 +			}
   4.767 +			printk("scsi : aborting command due to timeout : pid %lu, scsi%d,"
   4.768 +			       " channel %d, id %d, lun %d ",
   4.769 +			       SCpnt->pid, SCpnt->host->host_no, (int) SCpnt->channel,
   4.770 +			       (int) SCpnt->target, (int) SCpnt->lun);
   4.771 +			print_command(SCpnt->cmnd);
   4.772 +			if (SCpnt->serial_number != SCpnt->serial_number_at_timeout)
   4.773 +				return 0;
   4.774 +			SCpnt->abort_reason = why;
   4.775 +			switch (host->hostt->abort(SCpnt)) {
   4.776 +				/* We do not know how to abort.  Try waiting another
   4.777 +				 * time increment and see if this helps. Set the
   4.778 +				 * WAS_TIMEDOUT flag set so we do not try this twice
   4.779 +				 */
   4.780 +			case SCSI_ABORT_BUSY:	/* Tough call - returning 1 from
   4.781 +						 * this is too severe
   4.782 +						 */
   4.783 +			case SCSI_ABORT_SNOOZE:
   4.784 +				if (why == DID_TIME_OUT) {
   4.785 +					SCpnt->internal_timeout &= ~IN_ABORT;
   4.786 +					if (SCpnt->flags & WAS_TIMEDOUT) {
   4.787 +						return 1;	/* Indicate we cannot handle this.
   4.788 +								 * We drop down into the reset handler
   4.789 +								 * and try again
   4.790 +								 */
   4.791 +					} else {
   4.792 +						SCpnt->flags |= WAS_TIMEDOUT;
   4.793 +						oldto = SCpnt->timeout_per_command;
   4.794 +						update_timeout(SCpnt, oldto);
   4.795 +					}
   4.796 +				}
   4.797 +				return 0;
   4.798 +			case SCSI_ABORT_PENDING:
   4.799 +				if (why != DID_TIME_OUT) {
   4.800 +					update_timeout(SCpnt, oldto);
   4.801 +				}
   4.802 +				return 0;
   4.803 +			case SCSI_ABORT_SUCCESS:
   4.804 +				/* We should have already aborted this one.  No
   4.805 +				 * need to adjust timeout
   4.806 +				 */
   4.807 +				SCpnt->internal_timeout &= ~IN_ABORT;
   4.808 +				return 0;
   4.809 +			case SCSI_ABORT_NOT_RUNNING:
   4.810 +				SCpnt->internal_timeout &= ~IN_ABORT;
   4.811 +				update_timeout(SCpnt, 0);
   4.812 +				return 0;
   4.813 +			case SCSI_ABORT_ERROR:
   4.814 +			default:
   4.815 +				SCpnt->internal_timeout &= ~IN_ABORT;
   4.816 +				return 1;
   4.817 +			}
   4.818 +		}
   4.819 +	}
   4.820 +}
   4.821 +
   4.822 +
   4.823 +/* Mark a single SCSI Device as having been reset. */
   4.824 +
   4.825 +static inline void scsi_mark_device_reset(Scsi_Device * Device)
   4.826 +{
   4.827 +	Device->was_reset = 1;
   4.828 +	Device->expecting_cc_ua = 1;
   4.829 +}
   4.830 +
   4.831 +
   4.832 +/* Mark all SCSI Devices on a specific Host as having been reset. */
   4.833 +
   4.834 +void scsi_mark_host_reset(struct Scsi_Host *Host)
   4.835 +{
   4.836 +	Scsi_Cmnd *SCpnt;
   4.837 +	Scsi_Device *SDpnt;
   4.838 +
   4.839 +	for (SDpnt = Host->host_queue; SDpnt; SDpnt = SDpnt->next) {
   4.840 +		for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next)
   4.841 +			scsi_mark_device_reset(SCpnt->device);
   4.842 +	}
   4.843 +}
   4.844 +
   4.845 +
   4.846 +/* Mark all SCSI Devices on a specific Host Bus as having been reset. */
   4.847 +
   4.848 +static void scsi_mark_bus_reset(struct Scsi_Host *Host, int channel)
   4.849 +{
   4.850 +	Scsi_Cmnd *SCpnt;
   4.851 +	Scsi_Device *SDpnt;
   4.852 +
   4.853 +	for (SDpnt = Host->host_queue; SDpnt; SDpnt = SDpnt->next) {
   4.854 +		for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next)
   4.855 +			if (SCpnt->channel == channel)
   4.856 +				scsi_mark_device_reset(SCpnt->device);
   4.857 +	}
   4.858 +}
   4.859 +
   4.860 +
   4.861 +static int scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
   4.862 +{
   4.863 +	int temp;
   4.864 +	Scsi_Cmnd *SCpnt1;
   4.865 +	Scsi_Device *SDpnt;
   4.866 +	struct Scsi_Host *host = SCpnt->host;
   4.867 +
   4.868 +	printk("SCSI bus is being reset for host %d channel %d.\n",
   4.869 +	       host->host_no, SCpnt->channel);
   4.870 +
   4.871 +#if 0
   4.872 +	/*
   4.873 +	 * First of all, we need to make a recommendation to the low-level
   4.874 +	 * driver as to whether a BUS_DEVICE_RESET should be performed,
   4.875 +	 * or whether we should do a full BUS_RESET.  There is no simple
   4.876 +	 * algorithm here - we basically use a series of heuristics
   4.877 +	 * to determine what we should do.
   4.878 +	 */
   4.879 +	SCpnt->host->suggest_bus_reset = FALSE;
   4.880 +
   4.881 +	/*
   4.882 +	 * First see if all of the active devices on the bus have
   4.883 +	 * been jammed up so that we are attempting resets.  If so,
   4.884 +	 * then suggest a bus reset.  Forcing a bus reset could
   4.885 +	 * result in some race conditions, but no more than
   4.886 +	 * you would usually get with timeouts.  We will cross
   4.887 +	 * that bridge when we come to it.
   4.888 +	 *
   4.889 +	 * This is actually a pretty bad idea, since a sequence of
   4.890 +	 * commands will often timeout together and this will cause a
   4.891 +	 * Bus Device Reset followed immediately by a SCSI Bus Reset.
   4.892 +	 * If all of the active devices really are jammed up, the
   4.893 +	 * Bus Device Reset will quickly timeout and scsi_times_out
   4.894 +	 * will follow up with a SCSI Bus Reset anyway.
   4.895 +	 */
   4.896 +	SCpnt1 = host->host_queue;
   4.897 +	while (SCpnt1) {
   4.898 +		if (SCpnt1->request.rq_status != RQ_INACTIVE
   4.899 +		    && (SCpnt1->flags & (WAS_RESET | IS_RESETTING)) == 0)
   4.900 +			break;
   4.901 +		SCpnt1 = SCpnt1->next;
   4.902 +	}
   4.903 +	if (SCpnt1 == NULL) {
   4.904 +		reset_flags |= SCSI_RESET_SUGGEST_BUS_RESET;
   4.905 +	}
   4.906 +	/*
   4.907 +	 * If the code that called us is suggesting a hard reset, then
   4.908 +	 * definitely request it.  This usually occurs because a
   4.909 +	 * BUS_DEVICE_RESET times out.
   4.910 +	 *
   4.911 +	 * Passing reset_flags along takes care of this automatically.
   4.912 +	 */
   4.913 +	if (reset_flags & SCSI_RESET_SUGGEST_BUS_RESET) {
   4.914 +		SCpnt->host->suggest_bus_reset = TRUE;
   4.915 +	}
   4.916 +#endif
   4.917 +
   4.918 +	while (1) {
   4.919 +
   4.920 +		/*
   4.921 +		 * Protect against races here.  If the command is done, or we are
   4.922 +		 * on a different command forget it.
   4.923 +		 */
   4.924 +		if (reset_flags & SCSI_RESET_ASYNCHRONOUS)
   4.925 +			if (SCpnt->serial_number != SCpnt->serial_number_at_timeout) {
   4.926 +				return 0;
   4.927 +			}
   4.928 +		if (SCpnt->internal_timeout & IN_RESET) {
   4.929 +			spin_unlock_irq(&io_request_lock);
   4.930 +			while (SCpnt->internal_timeout & IN_RESET)
   4.931 +				barrier();
   4.932 +			spin_lock_irq(&io_request_lock);
   4.933 +		} else {
   4.934 +			SCpnt->internal_timeout |= IN_RESET;
   4.935 +			update_timeout(SCpnt, RESET_TIMEOUT);
   4.936 +
   4.937 +			if (reset_flags & SCSI_RESET_SYNCHRONOUS)
   4.938 +				SCpnt->flags |= SYNC_RESET;
   4.939 +			if (host->host_busy) {
   4.940 +				for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
   4.941 +					SCpnt1 = SDpnt->device_queue;
   4.942 +					while (SCpnt1) {
   4.943 +						if (SCpnt1->request.rq_status != RQ_INACTIVE) {
   4.944 +#if 0
   4.945 +							if (!(SCpnt1->flags & IS_RESETTING) &&
   4.946 +							    !(SCpnt1->internal_timeout & IN_ABORT))
   4.947 +								scsi_abort(SCpnt1, DID_RESET);
   4.948 +#endif
   4.949 +							SCpnt1->flags |= (WAS_RESET | IS_RESETTING);
   4.950 +						}
   4.951 +						SCpnt1 = SCpnt1->next;
   4.952 +					}
   4.953 +				}
   4.954 +
   4.955 +				host->last_reset = jiffies;
   4.956 +				host->resetting = 1;
   4.957 +				/*
   4.958 +				 * I suppose that the host reset callback will not play
   4.959 +				 * with the resetting field. We have just set the resetting
   4.960 +				 * flag here. -arca
   4.961 +				 */
   4.962 +				temp = host->hostt->reset(SCpnt, reset_flags);
   4.963 +				/*
   4.964 +				   This test allows the driver to introduce an additional bus
   4.965 +				   settle time delay by setting last_reset up to 20 seconds in
   4.966 +				   the future.  In the normal case where the driver does not
   4.967 +				   modify last_reset, it must be assumed that the actual bus
   4.968 +				   reset occurred immediately prior to the return to this code,
   4.969 +				   and so last_reset must be updated to the current time, so
   4.970 +				   that the delay in internal_cmnd will guarantee at least a
   4.971 +				   MIN_RESET_DELAY bus settle time.
   4.972 +				 */
   4.973 +				if (host->last_reset - jiffies > 20UL * HZ)
   4.974 +					host->last_reset = jiffies;
   4.975 +			} else {
   4.976 +				host->host_busy++;
   4.977 +				host->last_reset = jiffies;
   4.978 +				host->resetting = 1;
   4.979 +				SCpnt->flags |= (WAS_RESET | IS_RESETTING);
   4.980 +				/*
   4.981 +				 * I suppose that the host reset callback will not play
   4.982 +				 * with the resetting field. We have just set the resetting
   4.983 +				 * flag here. -arca
   4.984 +				 */
   4.985 +				temp = host->hostt->reset(SCpnt, reset_flags);
   4.986 +				if (time_before(host->last_reset, jiffies) ||
   4.987 +				    (time_after(host->last_reset, jiffies + 20 * HZ)))
   4.988 +					host->last_reset = jiffies;
   4.989 +				host->host_busy--;
   4.990 +			}
   4.991 +			if (reset_flags & SCSI_RESET_SYNCHRONOUS)
   4.992 +				SCpnt->flags &= ~SYNC_RESET;
   4.993 +
   4.994 +#ifdef DEBUG
   4.995 +			printk("scsi reset function returned %d\n", temp);
   4.996 +#endif
   4.997 +
   4.998 +			/*
   4.999 +			 * Now figure out what we need to do, based upon
  4.1000 +			 * what the low level driver said that it did.
  4.1001 +			 * If the result is SCSI_RESET_SUCCESS, SCSI_RESET_PENDING,
  4.1002 +			 * or SCSI_RESET_WAKEUP, then the low level driver did a
  4.1003 +			 * bus device reset or bus reset, so we should go through
  4.1004 +			 * and mark one or all of the devices on that bus
  4.1005 +			 * as having been reset.
  4.1006 +			 */
  4.1007 +			switch (temp & SCSI_RESET_ACTION) {
  4.1008 +			case SCSI_RESET_SUCCESS:
  4.1009 +				if (temp & SCSI_RESET_HOST_RESET)
  4.1010 +					scsi_mark_host_reset(host);
  4.1011 +				else if (temp & SCSI_RESET_BUS_RESET)
  4.1012 +					scsi_mark_bus_reset(host, SCpnt->channel);
  4.1013 +				else
  4.1014 +					scsi_mark_device_reset(SCpnt->device);
  4.1015 +				SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2 | IN_RESET3);
  4.1016 +				return 0;
  4.1017 +			case SCSI_RESET_PENDING:
  4.1018 +				if (temp & SCSI_RESET_HOST_RESET)
  4.1019 +					scsi_mark_host_reset(host);
  4.1020 +				else if (temp & SCSI_RESET_BUS_RESET)
  4.1021 +					scsi_mark_bus_reset(host, SCpnt->channel);
  4.1022 +				else
  4.1023 +					scsi_mark_device_reset(SCpnt->device);
  4.1024 +			case SCSI_RESET_NOT_RUNNING:
  4.1025 +				return 0;
  4.1026 +			case SCSI_RESET_PUNT:
  4.1027 +				SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2 | IN_RESET3);
  4.1028 +				scsi_request_sense(SCpnt);
  4.1029 +				return 0;
  4.1030 +			case SCSI_RESET_WAKEUP:
  4.1031 +				if (temp & SCSI_RESET_HOST_RESET)
  4.1032 +					scsi_mark_host_reset(host);
  4.1033 +				else if (temp & SCSI_RESET_BUS_RESET)
  4.1034 +					scsi_mark_bus_reset(host, SCpnt->channel);
  4.1035 +				else
  4.1036 +					scsi_mark_device_reset(SCpnt->device);
  4.1037 +				SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2 | IN_RESET3);
  4.1038 +				scsi_request_sense(SCpnt);
  4.1039 +				/*
  4.1040 +				 * If a bus reset was performed, we
  4.1041 +				 * need to wake up each and every command
  4.1042 +				 * that was active on the bus or if it was a HBA
  4.1043 +				 * reset all active commands on all channels
  4.1044 +				 */
  4.1045 +				if (temp & SCSI_RESET_HOST_RESET) {
  4.1046 +					for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
  4.1047 +						SCpnt1 = SDpnt->device_queue;
  4.1048 +						while (SCpnt1) {
  4.1049 +							if (SCpnt1->request.rq_status != RQ_INACTIVE
  4.1050 +							    && SCpnt1 != SCpnt)
  4.1051 +								scsi_request_sense(SCpnt1);
  4.1052 +							SCpnt1 = SCpnt1->next;
  4.1053 +						}
  4.1054 +					}
  4.1055 +				} else if (temp & SCSI_RESET_BUS_RESET) {
  4.1056 +					for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
  4.1057 +						SCpnt1 = SDpnt->device_queue;
  4.1058 +						while (SCpnt1) {
  4.1059 +							if (SCpnt1->request.rq_status != RQ_INACTIVE
  4.1060 +							&& SCpnt1 != SCpnt
  4.1061 +							    && SCpnt1->channel == SCpnt->channel)
  4.1062 +								scsi_request_sense(SCpnt);
  4.1063 +							SCpnt1 = SCpnt1->next;
  4.1064 +						}
  4.1065 +					}
  4.1066 +				}
  4.1067 +				return 0;
  4.1068 +			case SCSI_RESET_SNOOZE:
  4.1069 +				/* In this case, we set the timeout field to 0
  4.1070 +				 * so that this command does not time out any more,
  4.1071 +				 * and we return 1 so that we get a message on the
  4.1072 +				 * screen.
  4.1073 +				 */
  4.1074 +				SCpnt->internal_timeout &= ~(IN_RESET | IN_RESET2 | IN_RESET3);
  4.1075 +				update_timeout(SCpnt, 0);
  4.1076 +				/* If you snooze, you lose... */
  4.1077 +			case SCSI_RESET_ERROR:
  4.1078 +			default:
  4.1079 +				return 1;
  4.1080 +			}
  4.1081 +
  4.1082 +			return temp;
  4.1083 +		}
  4.1084 +	}
  4.1085 +}
  4.1086 +
  4.1087 +/*
  4.1088 + * The strategy is to cause the timer code to call scsi_times_out()
  4.1089 + * when the soonest timeout is pending.
  4.1090 + * The arguments are used when we are queueing a new command, because
  4.1091 + * we do not want to subtract the time used from this time, but when we
  4.1092 + * set the timer, we want to take this value into account.
  4.1093 + */
  4.1094 +
  4.1095 +int update_timeout(Scsi_Cmnd * SCset, int timeout)
  4.1096 +{
  4.1097 +	int rtn;
  4.1098 +
  4.1099 +	/*
  4.1100 +	 * We are using the new error handling code to actually register/deregister
  4.1101 +	 * timers for timeout.
  4.1102 +	 */
  4.1103 +
  4.1104 +	if (!timer_pending(&SCset->eh_timeout)) {
  4.1105 +		rtn = 0;
  4.1106 +	} else {
  4.1107 +		rtn = SCset->eh_timeout.expires - jiffies;
  4.1108 +	}
  4.1109 +
  4.1110 +	if (timeout == 0) {
  4.1111 +		scsi_delete_timer(SCset);
  4.1112 +	} else {
  4.1113 +		scsi_add_timer(SCset, timeout, scsi_old_times_out);
  4.1114 +	}
  4.1115 +
  4.1116 +	return rtn;
  4.1117 +}
  4.1118 +
  4.1119 +
  4.1120 +/*
  4.1121 + * This function exports SCSI Bus, Device or Host reset capability
  4.1122 + * and is for use with the SCSI generic driver.
  4.1123 + */
  4.1124 +int
  4.1125 +scsi_old_reset(Scsi_Cmnd *SCpnt, unsigned int flag)
  4.1126 +{
  4.1127 +	unsigned int old_flags = SCSI_RESET_SYNCHRONOUS;
  4.1128 +
  4.1129 +	switch(flag) {
  4.1130 +	case SCSI_TRY_RESET_DEVICE:
  4.1131 +		/* no suggestion flags to add, device reset is default */
  4.1132 +		break;
  4.1133 +	case SCSI_TRY_RESET_BUS:
  4.1134 +		old_flags |= SCSI_RESET_SUGGEST_BUS_RESET;
  4.1135 +		break;
  4.1136 +	case SCSI_TRY_RESET_HOST:
  4.1137 +		old_flags |= SCSI_RESET_SUGGEST_HOST_RESET;
  4.1138 +		break;
  4.1139 +	default:
  4.1140 +		return FAILED;
  4.1141 +	}
  4.1142 +
  4.1143 +	if (scsi_reset(SCpnt, old_flags))
  4.1144 +		return FAILED;
  4.1145 +	return SUCCESS;
  4.1146 +}
  4.1147 +
  4.1148 +/*
  4.1149 + * Overrides for Emacs so that we follow Linus's tabbing style.
  4.1150 + * Emacs will notice this stuff at the end of the file and automatically
  4.1151 + * adjust the settings for this buffer only.  This must remain at the end
  4.1152 + * of the file.
  4.1153 + * ---------------------------------------------------------------------------
  4.1154 + * Local variables:
  4.1155 + * c-indent-level: 4
  4.1156 + * c-brace-imaginary-offset: 0
  4.1157 + * c-brace-offset: -4
  4.1158 + * c-argdecl-indent: 4
  4.1159 + * c-label-offset: -4
  4.1160 + * c-continued-statement-offset: 4
  4.1161 + * c-continued-brace-offset: 0
  4.1162 + * indent-tabs-mode: nil
  4.1163 + * tab-width: 8
  4.1164 + * End:
  4.1165 + */