scsi.c 44 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*
 *	scsi.c Copyright (C) 1992 Drew Eckhardt 
 *	generic mid-level SCSI driver by
 *		Drew Eckhardt 
 *
 *	<drew@colorado.edu>
 *
 *	Bug correction thanks go to : 
 *		Rik Faith <faith@cs.unc.edu>
 *		Tommy Thorn <tthorn>
11 12 13 14 15
 *		Thomas Wuensche <tw@fgb1.fgb.mw.tu-muenchen.de>
 * 
 *       Modified by Eric Youngdale eric@tantalus.nrl.navy.mil to
 *       add scatter-gather, multiple outstanding request, and other
 *       enhancements.
16 17 18 19 20 21 22
 */

#include <asm/system.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>

Linus Torvalds's avatar
Linus Torvalds committed
23
#include "../block/blk.h"
24 25
#include "scsi.h"
#include "hosts.h"
26
#include "constants.h"
27 28

/*
Linus Torvalds's avatar
Linus Torvalds committed
29
static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.5 1993/09/24 12:45:18 drew Exp drew $";
30 31
*/

32 33 34
/* Command groups 3 and 4 are reserved and should never be used.  */
const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, 12, 12, 10, 10 };

Linus Torvalds's avatar
Linus Torvalds committed
35
#define INTERNAL_ERROR (panic ("Internal error in file %s, line %d.\n", __FILE__, __LINE__))
36

37 38
static void scsi_done (Scsi_Cmnd *SCpnt);
static int update_timeout (Scsi_Cmnd *, int);
39
static void print_inquiry(unsigned char *data);
40
static void scsi_times_out (Scsi_Cmnd * SCpnt);
41 42 43 44

static int time_start;
static int time_elapsed;

Linus Torvalds's avatar
Linus Torvalds committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#define MAX_SCSI_DEVICE_CODE 10
const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
{
 "Direct-Access    ",
 "Sequential-Access",
 "Printer          ",
 "Processor        ",
 "WORM             ",
 "CD-ROM           ",
 "Scanner          ",
 "Optical Device   ",
 "Medium Changer   ",
 "Communications   "
};


61 62 63 64 65 66 67 68 69
/*
	global variables : 
	NR_SCSI_DEVICES is the number of SCSI devices we have detected, 
	scsi_devices an array of these specifing the address for each 
	(host, id, LUN)
*/
	
int NR_SCSI_DEVICES=0;

70 71 72 73 74 75 76
Scsi_Device * scsi_devices = NULL;

static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0};

/* We make this not static so that we can read the array with gdb. */
/* static */ Scsi_Cmnd * last_cmnd = NULL;

77 78 79 80 81 82 83 84 85 86
/*
 *	As the scsi do command functions are inteligent, and may need to 
 *	redo a command, we need to keep track of the last command 
 *	executed on each one.
 */

#define WAS_RESET 	0x01
#define WAS_TIMEDOUT 	0x02
#define WAS_SENSE	0x04
#define IS_RESETTING	0x08
87
#define ASKED_FOR_SENSE 0x10
88
/* #define NEEDS_JUMPSTART 0x20  defined in hosts.h */
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

/*
 *	This is the number  of clock ticks we should wait before we time out 
 *	and abort the command.  This is for  where the scsi.c module generates 
 *	the command, not where it originates from a higher level, in which
 *	case the timeout is specified there.
 *
 *	ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT
 *	respectively.
 */

#ifdef DEBUG
	#define SCSI_TIMEOUT 500
#else
	#define SCSI_TIMEOUT 100
#endif

#ifdef DEBUG
	#define SENSE_TIMEOUT SCSI_TIMEOUT
	#define ABORT_TIMEOUT SCSI_TIMEOUT
	#define RESET_TIMEOUT SCSI_TIMEOUT
#else
	#define SENSE_TIMEOUT 50
	#define RESET_TIMEOUT 50
	#define ABORT_TIMEOUT 50
114
	#define MIN_RESET_DELAY 100
115 116
#endif

117 118 119 120 121 122 123 124 125 126 127
/* The following devices are known not to tolerate a lun != 0 scan for
   one reason or another.  Some will respond to all luns, others will
   lock up. */

     struct blist{
       char * vendor;
       char * model;
       char * revision; /* Latest revision known to be bad.  Not used yet */
     };

static struct blist blacklist[] = 
Linus Torvalds's avatar
Linus Torvalds committed
128
{
129
   {"DENON","DRD-25X","V"},   /* A cdrom that locks up when probed at lun != 0 */
Linus Torvalds's avatar
Linus Torvalds committed
130
   {"MAXTOR","XT-3280","PR02"},  /* Locks-up when LUN>0 polled. */
131
   {"MAXTOR","XT-4380S","B3C"},  /* Locks-up when LUN>0 polled. */
Linus Torvalds's avatar
Linus Torvalds committed
132 133 134
   {"MAXTOR","MXT-1240S","I1.2"}, /* Locks up when LUN > 0 polled */
   {"MAXTOR","XT-4170S","B5A"},  /* Locks-up sometimes when LUN>0 polled. */
   {"NEC","CD-ROM DRIVE:841","1.0"},  /* Locks-up when LUN>0 polled. */
Linus Torvalds's avatar
Linus Torvalds committed
135
   {"RODIME","RO3000S","2.33"},  /* Locks up if polled for lun != 0 */
Linus Torvalds's avatar
Linus Torvalds committed
136 137 138 139 140
   {"SEAGATE", "ST157N", "\004|j"}, /* causes failed REQUEST SENSE on lun 1 for aha152x
				     * controller, which causes SCSI code to reset bus.*/
   {"SEAGATE", "ST296","921"},   /* Responds to all lun */
   {"SONY","CD-ROM CDU-541","4.3d"},
   {"TANDBERG","TDC 3600","U07"},  /* Locks up if polled for lun != 0 */
141 142
   {"TEAC","CD-ROM","1.06"},	/* causes failed REQUEST SENSE on lun 1 for seagate
				 * controller, which causes SCSI code to reset bus.*/
Linus Torvalds's avatar
Linus Torvalds committed
143 144
   {"TEXEL","CD-ROM","1.06"},   /* causes failed REQUEST SENSE on lun 1 for seagate
				 * controller, which causes SCSI code to reset bus.*/
145 146
   {NULL, NULL, NULL}};	

147
static int blacklisted(unsigned char * response_data){
148
  int i = 0;
149
  unsigned char * pnt;
150 151
  for(i=0; 1; i++){
    if(blacklist[i].vendor == NULL) return 0;
152 153
    pnt = &response_data[8];
    while(*pnt && *pnt == ' ') pnt++;
154
    if(memcmp(blacklist[i].vendor, pnt,
155
	       strlen(blacklist[i].vendor))) continue;
156 157
    pnt = &response_data[16];
    while(*pnt && *pnt == ' ') pnt++;
158
    if(memcmp(blacklist[i].model, pnt,
159 160 161 162 163
	       strlen(blacklist[i].model))) continue;
    return 1;
  };	
};

164 165 166 167 168 169 170 171 172
/*
 *	As the actual SCSI command runs in the background, we must set up a 
 *	flag that tells scan_scsis() when the result it has is valid.  
 *	scan_scsis can set the_result to -1, and watch for it to become the 
 *	actual return code for that call.  the scan_scsis_done function() is 
 *	our user specified completion function that is passed on to the  
 *	scsi_do_cmd() function.
 */

173
static volatile int in_scan = 0;
174
static int the_result;
175
static void scan_scsis_done (Scsi_Cmnd * SCpnt)
176 177 178
	{
	
#ifdef DEBUG
179
	printk ("scan_scsis_done(%d, %06x)\n", SCpnt->host, SCpnt->result);
180
#endif	
181
	SCpnt->request.dev = 0xfffe;
182 183 184 185 186 187 188 189 190 191
	}
/*
 *	Detecting SCSI devices :	
 *	We scan all present host adapter's busses,  from ID 0 to ID 6.  
 *	We use the INQUIRY command, determine device type, and pass the ID / 
 *	lun address of all sequential devices to the tape driver, all random 
 *	devices to the disk driver.
 */

static void scan_scsis (void)
192
{
Linus Torvalds's avatar
Linus Torvalds committed
193
  int dev, lun, type;
194 195
  unsigned char scsi_cmd [12];
  unsigned char scsi_result [256];
Linus Torvalds's avatar
Linus Torvalds committed
196
  struct Scsi_Host * shpnt;
197 198 199 200 201 202 203
  Scsi_Cmnd  SCmd;
  
  ++in_scan;
  lun = 0;
  
  SCmd.next = NULL;
  SCmd.prev = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
204
  for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
205
      {
Linus Torvalds's avatar
Linus Torvalds committed
206 207
	shpnt->host_queue = &SCmd;  /* We need this so that
					 commands can time out */
208
	for (dev = 0; dev < 8; ++dev)
Linus Torvalds's avatar
Linus Torvalds committed
209
	  if (shpnt->this_id != dev)
210 211 212 213 214 215 216
/*
 * We need the for so our continue, etc. work fine.
 */

#ifdef NO_MULTI_LUN
	    for (lun = 0; lun < 1; ++lun)
#else
217
	    for (lun = 0; lun < 8; ++lun)
218
#endif
219
	      {
Linus Torvalds's avatar
Linus Torvalds committed
220
		scsi_devices[NR_SCSI_DEVICES].host = shpnt;
221 222 223 224
		scsi_devices[NR_SCSI_DEVICES].id = dev;
		scsi_devices[NR_SCSI_DEVICES].lun = lun;
		scsi_devices[NR_SCSI_DEVICES].index = NR_SCSI_DEVICES;
		scsi_devices[NR_SCSI_DEVICES].device_wait = NULL;
225 226 227 228 229
/*
 * Assume that the device will have handshaking problems, and then 
 * fix this field later if it turns out it doesn't.
 */
		scsi_devices[NR_SCSI_DEVICES].borken = 1;
230 231 232 233 234 235
		
		scsi_cmd[0] = TEST_UNIT_READY;
		scsi_cmd[1] = lun << 5;
		scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
		scsi_cmd[4] = 0;

Linus Torvalds's avatar
Linus Torvalds committed
236
		SCmd.host = shpnt;
237 238 239 240 241
		SCmd.target = dev;
		SCmd.lun = lun;

		SCmd.request.dev = 0xffff; /* Mark not busy */
		SCmd.use_sg  = 0;
242
		SCmd.old_use_sg  = 0;
243 244
		SCmd.transfersize = 0;
		SCmd.underflow = 0;
245
		SCmd.index = NR_SCSI_DEVICES;
246 247 248 249

		scsi_do_cmd (&SCmd,
			     (void *)  scsi_cmd, (void *) 
			     scsi_result, 256,  scan_scsis_done, 
250
			     SCSI_TIMEOUT + 400, 5);
251 252
		
		while (SCmd.request.dev != 0xfffe);
253 254 255 256 257
#if defined(DEBUG) || defined(DEBUG_INIT)
		printk("scsi: scan SCSIS id %d lun %d\n", dev, lun);
		printk("scsi: return code %08x\n", SCmd.result);
#endif

258 259 260 261 262 263

		if(SCmd.result) {
		  if ((driver_byte(SCmd.result)  & DRIVER_SENSE) &&
		      ((SCmd.sense_buffer[0] & 0x70) >> 4) == 7) {
		    if (SCmd.sense_buffer[2] &0xe0)
		      continue; /* No devices here... */
264 265
		    if(((SCmd.sense_buffer[2] & 0xf) != NOT_READY) &&
		       ((SCmd.sense_buffer[2] & 0xf) != UNIT_ATTENTION))
266 267 268 269 270 271
		      continue;
		  }
		  else
		    break;
		};

272 273 274 275
#if defined (DEBUG) || defined(DEBUG_INIT)
		printk("scsi: performing INQUIRY\n");
#endif

276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
		/*
		 * Build an INQUIRY command block.  
		 */
		
		scsi_cmd[0] = INQUIRY;
		scsi_cmd[1] = (lun << 5) & 0xe0;
		scsi_cmd[2] = 0;
		scsi_cmd[3] = 0;
		scsi_cmd[4] = 255;
		scsi_cmd[5] = 0;
		
		SCmd.request.dev = 0xffff; /* Mark not busy */
		
		scsi_do_cmd (&SCmd,
			     (void *)  scsi_cmd, (void *) 
			     scsi_result, 256,  scan_scsis_done, 
			     SCSI_TIMEOUT, 3);
		
		while (SCmd.request.dev != 0xfffe);
		
		the_result = SCmd.result;
		
298 299 300 301 302 303 304
#if defined(DEBUG) || defined(DEBUG_INIT)
		if (!the_result)
			printk("scsi: INQUIRY successful\n");
		else
			printk("scsi: INQUIRY failed with code %08x\n");
#endif

305
		if(the_result) break; 
306

307 308 309 310 311 312 313
		/* skip other luns on this device */
		
		if (!the_result)
		  {
		    scsi_devices[NR_SCSI_DEVICES].
		      removable = (0x80 & 
				   scsi_result[1]) >> 7;
314 315
		    scsi_devices[NR_SCSI_DEVICES].lockable =
		      scsi_devices[NR_SCSI_DEVICES].removable;
316 317 318 319 320 321
		    scsi_devices[NR_SCSI_DEVICES].
		      changed = 0;
		    scsi_devices[NR_SCSI_DEVICES].
		      access_count = 0;
		    scsi_devices[NR_SCSI_DEVICES].
		      busy = 0;
322 323 324 325 326 327
/* 
 *	Currently, all sequential devices are assumed to be tapes,
 *	all random devices disk, with the appropriate read only 
 *	flags set for ROM / WORM treated as RO.
 */ 

328 329 330 331
		    switch (type = scsi_result[0])
		      {
		      case TYPE_TAPE :
		      case TYPE_DISK :
332
		      case TYPE_MOD :
333 334 335 336 337 338 339
			scsi_devices[NR_SCSI_DEVICES].writeable = 1;
			break;
		      case TYPE_WORM :
		      case TYPE_ROM :
			scsi_devices[NR_SCSI_DEVICES].writeable = 0;
			break;
			default :
340 341 342 343 344 345
#if 0
#ifdef DEBUG
			printk("scsi: unknown type %d\n", type);
			print_inquiry(scsi_result);
#endif
#endif
346 347 348 349 350 351 352 353 354 355 356 357 358
			  type = -1;
		      }

		    scsi_devices[NR_SCSI_DEVICES].random = 
		      (type == TYPE_TAPE) ? 0 : 1;
		    scsi_devices[NR_SCSI_DEVICES].type = type;

		    if (type != -1)
		      {
			print_inquiry(scsi_result);
			switch(type){
			case TYPE_TAPE:
			  printk("Detected scsi tape st%d at scsi%d, id %d, lun %d\n", MAX_ST,
Linus Torvalds's avatar
Linus Torvalds committed
359
				 shpnt->host_no , dev, lun); 
360 361 362 363
			  if(NR_ST != -1) ++MAX_ST;
			  break;
			case TYPE_ROM:
			  printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", MAX_SR,
Linus Torvalds's avatar
Linus Torvalds committed
364
				 shpnt->host_no , dev, lun); 
365 366 367
			  if(NR_SR != -1) ++MAX_SR;
			  break;
			case TYPE_DISK:
368
			case TYPE_MOD:
Linus Torvalds's avatar
Linus Torvalds committed
369
			  printk("Detected scsi disk sd%c at scsi%d, id %d, lun %d\n", 'a'+MAX_SD,
Linus Torvalds's avatar
Linus Torvalds committed
370
				 shpnt->host_no , dev, lun); 
371 372 373 374 375 376
			  if(NR_SD != -1) ++MAX_SD;
			  break;
			default:
			  break;
			};

Linus Torvalds's avatar
Linus Torvalds committed
377 378
			if(NR_SG != -1) ++MAX_SG;

379 380 381 382 383 384
			scsi_devices[NR_SCSI_DEVICES].scsi_level =
			  scsi_result[2] & 0x07;
			if (scsi_devices[NR_SCSI_DEVICES].scsi_level >= 2 ||
			    (scsi_devices[NR_SCSI_DEVICES].scsi_level == 1 &&
			     (scsi_result[3] & 0x0f) == 1))
			  scsi_devices[NR_SCSI_DEVICES].scsi_level++;
Linus Torvalds's avatar
Linus Torvalds committed
385 386 387 388 389 390 391
/* 
 * Set the tagged_queue flag for SCSI-II devices that purport to support
 * tagged queuing in the INQUIRY data.
 */

			scsi_devices[NR_SCSI_DEVICES].tagged_queue = 0;

Linus Torvalds's avatar
Linus Torvalds committed
392
			if ((scsi_devices[NR_SCSI_DEVICES].scsi_level >= SCSI_2) &&
Linus Torvalds's avatar
Linus Torvalds committed
393 394 395 396 397 398 399 400 401 402 403
			    (scsi_result[7] & 2)) {
			    scsi_devices[NR_SCSI_DEVICES].tagged_supported = 1;
			    scsi_devices[NR_SCSI_DEVICES].current_tag = 0;
			}

/*
 * Accomodate drivers that want to sleep when they should be in a polling
 * loop.
 */

			scsi_devices[NR_SCSI_DEVICES].disconnect = 0;
404

405 406 407 408 409 410 411 412
/*
 * Some revisions of the Texel CD ROM drives have handshaking
 * problems when used with the Seagate controllers.  Before we
 * know what type of device we're talking to, we assume it's 
 * borken and then change it here if it turns out that it isn't
 * a TEXEL drive.
 */

Linus Torvalds's avatar
Linus Torvalds committed
413 414
			if(strncmp("TEXEL", (char *) &scsi_result[8], 5) != 0 ||
			  strncmp("CD-ROM", (char *) &scsi_result[16], 6) != 0 
415 416 417 418 419 420 421
/* 
 * XXX 1.06 has problems, some one should figure out the others too so
 * ALL TEXEL drives don't suffer in performance, especially when I finish
 * integrating my seagate patches which do multiple I_T_L nexuses.
 */

#ifdef notyet
Linus Torvalds's avatar
Linus Torvalds committed
422
			   || (strncmp("1.06", (char *) &scsi_result[[, 4) != 0)
423 424 425 426 427
#endif
			   )
			   scsi_devices[NR_SCSI_DEVICES].borken = 0;


428 429
			/* These devices need this "key" to unlock the device
			   so we can use it */
430 431 432
			if(memcmp("INSITE", &scsi_result[8], 6) == 0 &&
			   (memcmp("Floptical   F*8I", &scsi_result[16], 16) == 0
			    || memcmp("I325VM", &scsi_result[16], 6) == 0)) {
433 434
			  printk("Unlocked floptical drive.\n");
			  scsi_devices[NR_SCSI_DEVICES].lockable = 0;
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
			  scsi_cmd[0] = MODE_SENSE;
			  scsi_cmd[1] = (lun << 5) & 0xe0;
			  scsi_cmd[2] = 0x2e;
			  scsi_cmd[3] = 0;
			  scsi_cmd[4] = 0x2a;
			  scsi_cmd[5] = 0;
		
			  SCmd.request.dev = 0xffff; /* Mark not busy */
			  
			  scsi_do_cmd (&SCmd,
				       (void *)  scsi_cmd, (void *) 
				       scsi_result, 0x2a,  scan_scsis_done, 
				       SCSI_TIMEOUT, 3);
		
			  while (SCmd.request.dev != 0xfffe);
			};

			++NR_SCSI_DEVICES;
			/* Some scsi devices cannot be polled for lun != 0
			   due to firmware bugs */
			if(blacklisted(scsi_result)) break;
Linus Torvalds's avatar
Linus Torvalds committed
456 457 458
			/* Old drives like the MAXTOR XT-3280 say vers=0 */
			if ((scsi_result[2] & 0x07) == 0)
			    break;
459 460 461 462 463 464 465
			/* Some scsi-1 peripherals do not handle lun != 0.
			   I am assuming that scsi-2 peripherals do better */
			if((scsi_result[2] & 0x07) == 1 && 
			   (scsi_result[3] & 0x0f) == 0) break;
			}
		  }       /* if result == DID_OK ends */
	      }       /* for lun ends */
Linus Torvalds's avatar
Linus Torvalds committed
466
	shpnt->host_queue = NULL;  /* No longer needed here */
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
      }      	/* if present */  
  
  printk("scsi : detected ");
  if(NR_SD != -1)
    printk("%d SCSI disk%s ", MAX_SD, (MAX_SD != 1) ? "s" : "");
	 
  if(NR_ST != -1)
    printk("%d tape%s ", MAX_ST, (MAX_ST != 1) ? "s" : "");

  if(NR_SR != -1)
    printk("%d CD-ROM drive%s ", MAX_SR, (MAX_SR != 1) ? "s" : "");

  printk("total.\n");
  in_scan = 0;
}       /* scan_scsis  ends */
482 483 484 485 486 487 488 489 490 491 492 493 494 495

/*
 *	Flag bits for the internal_timeout array 
 */

#define NORMAL_TIMEOUT 0
#define IN_ABORT 1
#define IN_RESET 2
/*
	This is our time out function, called when the timer expires for a 
	given host adapter.  It will attempt to abort the currently executing 
	command, that failing perform a kernel panic.
*/ 

496
static void scsi_times_out (Scsi_Cmnd * SCpnt)
497 498
	{
	
499
 	switch (SCpnt->internal_timeout & (IN_ABORT | IN_RESET))
500 501 502
		{
		case NORMAL_TIMEOUT:
			if (!in_scan)
503
			      printk("SCSI host %d timed out - aborting command\n",
Linus Torvalds's avatar
Linus Torvalds committed
504
				SCpnt->host->host_no);
505
			
506
			if (!scsi_abort	(SCpnt, DID_TIME_OUT))
507 508
				return;				
		case IN_ABORT:
509
			printk("SCSI host %d abort() timed out - reseting\n",
Linus Torvalds's avatar
Linus Torvalds committed
510
				SCpnt->host->host_no);
511
			if (!scsi_reset (SCpnt)) 
512 513 514
				return;
		case IN_RESET:
		case (IN_ABORT | IN_RESET):
Linus Torvalds's avatar
Linus Torvalds committed
515
			panic("Unable to reset scsi host %d\n",SCpnt->host->host_no);
516 517 518 519 520 521
		default:
			INTERNAL_ERROR;
		}
					
	}

522 523 524 525 526 527 528 529 530 531

/* This function takes a quick look at a request, and decides if it
can be queued now, or if there would be a stall while waiting for
something else to finish.  This routine assumes that interrupts are
turned off when entering the routine.  It is the responsibility
of the calling code to ensure that this is the case. */

Scsi_Cmnd * request_queueable (struct request * req, int index)
{
  Scsi_Cmnd * SCpnt = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
532 533
  int tablesize;
  struct buffer_head * bh;
534 535 536 537 538 539 540

  if ((index < 0) ||  (index > NR_SCSI_DEVICES))
    panic ("Index number in allocate_device() is out of range.\n");
  
  if (req && req->dev <= 0)
    panic("Invalid device in allocate_device");
  
Linus Torvalds's avatar
Linus Torvalds committed
541
  SCpnt =  scsi_devices[index].host->host_queue;
542 543 544 545 546 547 548 549 550
    while(SCpnt){
      if(SCpnt->target == scsi_devices[index].id &&
	 SCpnt->lun == scsi_devices[index].lun)
	if(SCpnt->request.dev < 0) break;
      SCpnt = SCpnt->next;
    };

  if (!SCpnt) return NULL;

Linus Torvalds's avatar
Linus Torvalds committed
551 552
  if (scsi_devices[index].host->hostt->can_queue
      && scsi_devices[index].host->host_busy >= scsi_devices[index].host->hostt->can_queue) return NULL;
553 554 555

  if (req) {
    memcpy(&SCpnt->request, req, sizeof(struct request));
Linus Torvalds's avatar
Linus Torvalds committed
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
    tablesize = scsi_devices[index].host->sg_tablesize;
    bh = req->bh;
    if(!tablesize) bh = NULL;
    /* Take a quick look through the table to see how big it is.  We already
       have our copy of req, so we can mess with that if we want to.  */
    while(req->nr_sectors && bh){
	    tablesize--;
	    req->nr_sectors -= bh->b_size >> 9;
	    req->sector += bh->b_size >> 9;
	    if(!tablesize) break;
	    bh = bh->b_reqnext;
    };
    if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
      SCpnt->request.bhtail = bh;
      req->bh = bh->b_reqnext; /* Divide request */
      bh->b_reqnext = NULL;
      bh = req->bh;

      /* Now reset things so that req looks OK */
      SCpnt->request.nr_sectors -= req->nr_sectors;
      req->current_nr_sectors = bh->b_size >> 9;
      req->buffer = bh->b_data;
      SCpnt->request.waiting = NULL; /* Wait until whole thing done */
    } else
      req->dev = -1;
      
582
  } else {
583
    SCpnt->request.dev = 0xffff; /* Busy, but no request */
584 585
    SCpnt->request.waiting = NULL;  /* And no one is waiting for the device either */
  };
586 587

  SCpnt->use_sg = 0;  /* Reset the scatter-gather flag */
588
  SCpnt->old_use_sg  = 0;
589 590
  SCpnt->transfersize = 0;
  SCpnt->underflow = 0;
591 592 593 594 595 596 597 598 599 600 601 602 603 604
  return SCpnt;
}

/* This function returns a structure pointer that will be valid for
the device.  The wait parameter tells us whether we should wait for
the unit to become free or not.  We are also able to tell this routine
not to return a descriptor if the host is unable to accept any more
commands for the time being.  We need to keep in mind that there is no
guarantee that the host remain not busy.  Keep in mind the
request_queueable function also knows the internal allocation scheme
of the packets for each device */

Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
{
Linus Torvalds's avatar
Linus Torvalds committed
605
  int dev = -1;
606
  struct request * req = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
607 608 609
  int tablesize;
  struct buffer_head * bh;
  struct Scsi_Host * host;
610 611 612 613 614 615 616 617
  Scsi_Cmnd * SCpnt = NULL;
  Scsi_Cmnd * SCwait = NULL;

  if ((index < 0) ||  (index > NR_SCSI_DEVICES))
    panic ("Index number in allocate_device() is out of range.\n");
  
  if (reqp) req = *reqp;

618 619
    /* See if this request has already been queued by an interrupt routine */
  if (req && (dev = req->dev) <= 0) return NULL;
620
  
Linus Torvalds's avatar
Linus Torvalds committed
621
  host = scsi_devices[index].host;
622 623
  
  while (1==1){
Linus Torvalds's avatar
Linus Torvalds committed
624
    SCpnt = host->host_queue;
625 626 627 628 629 630 631 632 633 634
    while(SCpnt){
      if(SCpnt->target == scsi_devices[index].id &&
	 SCpnt->lun == scsi_devices[index].lun) {
	SCwait = SCpnt;
	if(SCpnt->request.dev < 0) break;
      };
      SCpnt = SCpnt->next;
    };
    cli();
    /* See if this request has already been queued by an interrupt routine */
635 636 637 638
    if (req && ((req->dev < 0) || (req->dev != dev))) {
      sti();
      return NULL;
    };
639 640 641 642 643 644 645 646 647 648 649 650 651 652
    if (!SCpnt || SCpnt->request.dev >= 0)  /* Might have changed */
      {
	sti();
	if(!wait) return NULL;
	if (!SCwait) {
	  printk("Attempt to allocate device index %d, target %d, lun %d\n",
		 index, scsi_devices[index].id ,scsi_devices[index].lun);
	  panic("No device found in allocate_device\n");
	};
	SCSI_SLEEP(&scsi_devices[SCwait->index].device_wait, 
		   (SCwait->request.dev > 0));
      } else {
	if (req) {
	  memcpy(&SCpnt->request, req, sizeof(struct request));
Linus Torvalds's avatar
Linus Torvalds committed
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
	  tablesize = scsi_devices[index].host->sg_tablesize;
	  bh = req->bh;
	  if(!tablesize) bh = NULL;
	  /* Take a quick look through the table to see how big it is.  We already
	     have our copy of req, so we can mess with that if we want to.  */
	  while(req->nr_sectors && bh){
	    tablesize--;
	    req->nr_sectors -= bh->b_size >> 9;
	    req->sector += bh->b_size >> 9;
	    if(!tablesize) break;
	    bh = bh->b_reqnext;
	  };
	  if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
	    SCpnt->request.bhtail = bh;
	    req->bh = bh->b_reqnext; /* Divide request */
	    bh->b_reqnext = NULL;
	    bh = req->bh;
	    /* Now reset things so that req looks OK */
	    SCpnt->request.nr_sectors -= req->nr_sectors;
	    req->current_nr_sectors = bh->b_size >> 9;
	    req->buffer = bh->b_data;
	    SCpnt->request.waiting = NULL; /* Wait until whole thing done */
	  }
	  else 
	    {
	      req->dev = -1;
	      *reqp = req->next;
	    };
681 682
	} else {
	  SCpnt->request.dev = 0xffff; /* Busy */
683
	  SCpnt->request.waiting = NULL;  /* And no one is waiting for this to complete */
684 685 686 687 688 689 690
	};
	sti();
	break;
      };
  };

  SCpnt->use_sg = 0;  /* Reset the scatter-gather flag */
691
  SCpnt->old_use_sg  = 0;
692 693
  SCpnt->transfersize = 0;      /* No default transfer size */
  SCpnt->underflow = 0;         /* Do not flag underflow conditions */
694 695 696
  return SCpnt;
}

697 698 699 700
/*
	This is inline because we have stack problemes if we recurse to deeply.
*/
			 
701
inline void internal_cmnd (Scsi_Cmnd * SCpnt)
702
	{
Linus Torvalds's avatar
Linus Torvalds committed
703 704
	int temp;
	struct Scsi_Host * host;
705 706 707 708
#ifdef DEBUG_DELAY	
	int clock;
#endif

709 710 711
	if ((unsigned long) &SCpnt < current->kernel_stack_page)
	  panic("Kernel stack overflow.");

712
	host = SCpnt->host;
713 714 715 716 717

/*
	We will wait MIN_RESET_DELAY clock ticks after the last reset so 
	we can avoid the drive not being ready.
*/ 
Linus Torvalds's avatar
Linus Torvalds committed
718
temp = host->last_reset;
719 720
while (jiffies < temp);

721
update_timeout(SCpnt, SCpnt->timeout_per_command);
722 723 724 725 726 727 728

/*
	We will use a queued command if possible, otherwise we will emulate the
	queing and calling of completion function ourselves. 
*/
#ifdef DEBUG
	printk("internal_cmnd (host = %d, target = %d, command = %08x, buffer =  %08x, \n"
Linus Torvalds's avatar
Linus Torvalds committed
729
		"bufflen = %d, done = %08x)\n", SCpnt->host->host_no, SCpnt->target, SCpnt->cmnd, SCpnt->buffer, SCpnt->bufflen, SCpnt->done);
730 731
#endif

Linus Torvalds's avatar
Linus Torvalds committed
732
        if (host->hostt->can_queue)
733 734 735
		{
#ifdef DEBUG
	printk("queuecommand : routine at %08x\n", 
Linus Torvalds's avatar
Linus Torvalds committed
736
		host->hostt->queuecommand);
737
#endif
Linus Torvalds's avatar
Linus Torvalds committed
738
                host->hostt->queuecommand (SCpnt, scsi_done);
739 740 741 742 743
		}
	else
		{

#ifdef DEBUG
Linus Torvalds's avatar
Linus Torvalds committed
744
	printk("command() :  routine at %08x\n", host->hostt->command);
745
#endif
Linus Torvalds's avatar
Linus Torvalds committed
746
		temp=host->hostt->command (SCpnt);
747
	        SCpnt->result = temp;
748 749 750
#ifdef DEBUG_DELAY
	clock = jiffies + 400;
	while (jiffies < clock);
Linus Torvalds's avatar
Linus Torvalds committed
751
	printk("done(host = %d, result = %04x) : routine at %08x\n", host->host_no, temp, done);
752
#endif
753
	        scsi_done(SCpnt);
754 755 756 757 758 759
		}	
#ifdef DEBUG
	printk("leaving internal_cmnd()\n");
#endif
	}	

760
static void scsi_request_sense (Scsi_Cmnd * SCpnt)
761 762
	{
	cli();
763
	SCpnt->flags |= WAS_SENSE | ASKED_FOR_SENSE;
764
	update_timeout(SCpnt, SENSE_TIMEOUT);
765 766 767
	sti();
	

768 769
	memcpy ((void *) SCpnt->cmnd , (void *) generic_sense,
		sizeof(generic_sense));
770

771 772
	SCpnt->cmnd[1] = SCpnt->lun << 5;	
	SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer);
773

774 775
	SCpnt->request_buffer = &SCpnt->sense_buffer;
	SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
776
	SCpnt->use_sg = 0;
777
	internal_cmnd (SCpnt);
778
	SCpnt->use_sg = SCpnt->old_use_sg;
779
	}
780 781 782 783 784 785 786 787 788 789



/*
	scsi_do_cmd sends all the commands out to the low-level driver.  It 
	handles the specifics required for each low level driver - ie queued 
	or non queud.  It also prevents conflicts when different high level 
	drivers go for the same host at the same time.
*/

790 791 792
void scsi_do_cmd (Scsi_Cmnd * SCpnt, const void *cmnd , 
		  void *buffer, unsigned bufflen, void (*done)(Scsi_Cmnd *),
		  int timeout, int retries 
793 794
		   )
        {
Linus Torvalds's avatar
Linus Torvalds committed
795
	struct Scsi_Host * host = SCpnt->host;
796 797

#ifdef DEBUG
798
	{
799
	int i;	
800
	int target = SCpnt->target;
801 802
	printk ("scsi_do_cmd (host = %d, target = %d, buffer =%08x, "
		"bufflen = %d, done = %08x, timeout = %d, retries = %d)\n"
Linus Torvalds's avatar
Linus Torvalds committed
803
		"command : " , host->host_no, target, buffer, bufflen, done, timeout, retries);
804 805 806
	for (i = 0; i < 10; ++i)
		printk ("%02x  ", ((unsigned char *) cmnd)[i]); 
	printk("\n");
807
      };
808 809
#endif
	
Linus Torvalds's avatar
Linus Torvalds committed
810
	if (!host)
811
		{
Linus Torvalds's avatar
Linus Torvalds committed
812
		panic ("Invalid or not present host. %d\n", host->host_no);
813 814 815 816 817 818 819 820 821 822 823
		}

	
/*
	We must prevent reentrancy to the lowlevel host driver.  This prevents 
	it - we enter a loop until the host we want to talk to is not busy.   
	Race conditions are prevented, as interrupts are disabled inbetween the
	time we check for the host being not busy, and the time we mark it busy
	ourselves.
*/

824 825
	while (1==1){
	  cli();
Linus Torvalds's avatar
Linus Torvalds committed
826 827
	  if (host->hostt->can_queue
	      && host->host_busy >= host->hostt->can_queue)
828 829
	    {
	      sti();
Linus Torvalds's avatar
Linus Torvalds committed
830 831
	      SCSI_SLEEP(&host->host_wait, 
			 (host->host_busy >= host->hostt->can_queue));
832
	    } else {
Linus Torvalds's avatar
Linus Torvalds committed
833
	      host->host_busy++;
834 835 836 837
	      sti();
	      break;
	    };
      };
838 839 840 841 842 843 844 845
/*
	Our own function scsi_done (which marks the host as not busy, disables 
	the timeout counter, etc) will be called by us or by the 
	scsi_hosts[host].queuecommand() function needs to also call
	the completion function for the high level driver.

*/

Linus Torvalds's avatar
Linus Torvalds committed
846
	memcpy ((void *) SCpnt->data_cmnd , (void *) cmnd, 12);
847 848 849 850 851 852 853 854 855 856 857 858
#if 0
	SCpnt->host = host;
	SCpnt->target = target;
	SCpnt->lun = (SCpnt->data_cmnd[1] >> 5);
#endif
	SCpnt->bufflen = bufflen;
	SCpnt->buffer = buffer;
	SCpnt->flags=0;
	SCpnt->retries=0;
	SCpnt->allowed=retries;
	SCpnt->done = done;
	SCpnt->timeout_per_command = timeout;
859
				
Linus Torvalds's avatar
Linus Torvalds committed
860
	memcpy ((void *) SCpnt->cmnd , (void *) cmnd, 12);
861 862 863
	/* Zero the sense buffer.  Some host adapters automatically request
	   sense on error.  0 is not a valid sense code.  */
	memset ((void *) SCpnt->sense_buffer, 0, sizeof SCpnt->sense_buffer);
864 865
	SCpnt->request_buffer = buffer;
	SCpnt->request_bufflen = bufflen;
866
	SCpnt->old_use_sg = SCpnt->use_sg;
867

868 869
	/* Start the timer ticking.  */

870 871
	SCpnt->internal_timeout = 0;
	internal_cmnd (SCpnt);
872 873 874 875 876 877 878

#ifdef DEBUG
	printk ("Leaving scsi_do_cmd()\n");
#endif
        }


879

880 881 882 883 884 885
/*
	The scsi_done() function disables the timeout timer for the scsi host, 
	marks the host as not busy, and calls the user specified completion 
	function for that host's current command.
*/

886
static void reset (Scsi_Cmnd * SCpnt)
Linus Torvalds's avatar
Linus Torvalds committed
887 888 889 890 891
{
#ifdef DEBUG
	printk("scsi: reset(%d)\n", SCpnt->host->host_no);
#endif
	
892 893
	SCpnt->flags |= (WAS_RESET | IS_RESETTING);
	scsi_reset(SCpnt);
Linus Torvalds's avatar
Linus Torvalds committed
894 895 896 897 898
	
#ifdef DEBUG
	printk("performing request sense\n");
#endif
	
899 900 901 902
	if(SCpnt->flags & NEEDS_JUMPSTART) {
	  SCpnt->flags &= ~NEEDS_JUMPSTART;
	  scsi_request_sense (SCpnt);
	};
Linus Torvalds's avatar
Linus Torvalds committed
903
}
904 905 906
	
	

907
static int check_sense (Scsi_Cmnd * SCpnt)
908
	{
909 910 911 912 913 914 915 916 917 918 919
  /* If there is no sense information, request it.  If we have already
     requested it, there is no point in asking again - the firmware must be
     confused. */
  if (((SCpnt->sense_buffer[0] & 0x70) >> 4) != 7) {
    if(!(SCpnt->flags & ASKED_FOR_SENSE))
      return SUGGEST_SENSE;
    else
      return SUGGEST_RETRY;
      }
  
  SCpnt->flags &= ~ASKED_FOR_SENSE;
920 921

#ifdef DEBUG_INIT
Linus Torvalds's avatar
Linus Torvalds committed
922
	printk("scsi%d : ", SCpnt->host->host_no);
923 924 925
	print_sense("", SCpnt);
	printk("\n");
#endif
926 927
	        if (SCpnt->sense_buffer[2] &0xe0)
		  return SUGGEST_ABORT;
928

929
		switch (SCpnt->sense_buffer[2] & 0xf)
930 931 932
		{
		case NO_SENSE:
			return 0;
Linus Torvalds's avatar
Linus Torvalds committed
933 934 935 936 937
		case RECOVERED_ERROR:
			if (scsi_devices[SCpnt->index].type == TYPE_TAPE)
			  return SUGGEST_IS_OK;
			else
			  return 0;
938 939 940

		case ABORTED_COMMAND:
			return SUGGEST_RETRY;	
941
		case NOT_READY:
942 943 944
		case UNIT_ATTENTION:
			return SUGGEST_ABORT;

945 946 947 948 949 950 951 952 953 954 955 956 957 958
		/* these three are not supported */	
		case COPY_ABORTED:
		case VOLUME_OVERFLOW:
		case MISCOMPARE:
	
		case MEDIUM_ERROR:
			return SUGGEST_REMAP;
		case BLANK_CHECK:
		case DATA_PROTECT:
		case HARDWARE_ERROR:
		case ILLEGAL_REQUEST:
		default:
			return SUGGEST_ABORT;
		}
959
	      }
960

961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981
/* This function is the mid-level interrupt routine, which decides how
 *  to handle error conditions.  Each invocation of this function must
 *  do one and *only* one of the following:
 *
 *  (1) Call last_cmnd[host].done.  This is done for fatal errors and
 *      normal completion, and indicates that the handling for this
 *      request is complete.
 *  (2) Call internal_cmnd to requeue the command.  This will result in
 *      scsi_done being called again when the retry is complete.
 *  (3) Call scsi_request_sense.  This asks the host adapter/drive for
 *      more information about the error condition.  When the information
 *      is available, scsi_done will be called again.
 *  (4) Call reset().  This is sort of a last resort, and the idea is that
 *      this may kick things loose and get the drive working again.  reset()
 *      automatically calls scsi_request_sense, and thus scsi_done will be
 *      called again once the reset is complete.
 *
 *      If none of the above actions are taken, the drive in question
 * will hang. If more than one of the above actions are taken by
 * scsi_done, then unpredictable behavior will result.
 */
982
static void scsi_done (Scsi_Cmnd * SCpnt)
983 984 985 986 987
	{
	int status=0;
	int exit=0;
	int checked;
	int oldto;
Linus Torvalds's avatar
Linus Torvalds committed
988
	struct Scsi_Host * host = SCpnt->host;
989 990
	int result = SCpnt->result;
	oldto = update_timeout(SCpnt, 0);
991 992 993 994

#define FINISHED 0
#define MAYREDO  1
#define REDO	 3
995
#define PENDING  4
996 997

#ifdef DEBUG
Linus Torvalds's avatar
Linus Torvalds committed
998
	printk("In scsi_done(host = %d, result = %06x)\n", host->host_no, result);
999 1000 1001 1002
#endif
	switch (host_byte(result))	
	{
	case DID_OK:
1003
		if (SCpnt->flags & IS_RESETTING)
1004
			{
1005
			SCpnt->flags &= ~IS_RESETTING;
1006 1007 1008 1009
			status = REDO;
			break;
			}

1010 1011
		if (status_byte(result) && (SCpnt->flags & WAS_SENSE))
			/* Failed to obtain sense information */
1012
			{
1013 1014
			SCpnt->flags &= ~WAS_SENSE;
			SCpnt->internal_timeout &= ~SENSE_TIMEOUT;
1015

1016
			if (!(SCpnt->flags & WAS_RESET))
1017
				{
1018
				printk("scsi%d : target %d lun %d request sense failed, performing reset.\n", 
Linus Torvalds's avatar
Linus Torvalds committed
1019
					SCpnt->host->host_no, SCpnt->target, SCpnt->lun);
1020
				reset(SCpnt);
1021 1022
				return;
				}
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
			else
				{
				exit = (DRIVER_HARD | SUGGEST_ABORT);
				status = FINISHED;
				}
			}
		else switch(msg_byte(result))
			{
			case COMMAND_COMPLETE:
			switch (status_byte(result))
			{
			case GOOD:
1035
				if (SCpnt->flags & WAS_SENSE)
1036 1037 1038 1039 1040
					{
#ifdef DEBUG
	printk ("In scsi_done, GOOD status, COMMAND COMPLETE, parsing sense information.\n");
#endif

1041 1042
					SCpnt->flags &= ~WAS_SENSE;
					SCpnt->internal_timeout &= ~SENSE_TIMEOUT;
1043
	
1044
					switch (checked = check_sense(SCpnt))
1045
					{
1046
					case SUGGEST_SENSE:
1047 1048 1049 1050 1051
					case 0: 
#ifdef DEBUG
	printk("NO SENSE.  status = REDO\n");
#endif

1052
						update_timeout(SCpnt, oldto);
1053 1054
						status = REDO;
						break;
Linus Torvalds's avatar
Linus Torvalds committed
1055 1056
      					case SUGGEST_IS_OK:
						break;
1057 1058 1059 1060 1061 1062 1063
					case SUGGEST_REMAP:			
					case SUGGEST_RETRY: 
#ifdef DEBUG
	printk("SENSE SUGGEST REMAP or SUGGEST RETRY - status = MAYREDO\n");
#endif

						status = MAYREDO;
1064
						exit = DRIVER_SENSE | SUGGEST_RETRY;
1065 1066 1067 1068 1069 1070 1071
						break;
					case SUGGEST_ABORT:
#ifdef DEBUG
	printk("SENSE SUGGEST ABORT - status = FINISHED");
#endif

						status = FINISHED;
1072
						exit =  DRIVER_SENSE | SUGGEST_ABORT;
1073 1074
						break;
					default:
1075
						printk ("Internal error %s %d \n", __FILE__, 
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
							__LINE__);
					}			   
					}	
				else
					{
#ifdef DEBUG
	printk("COMMAND COMPLETE message returned, status = FINISHED. \n");
#endif

					exit =  DRIVER_OK;
					status = FINISHED;
					}
				break;	

			case CHECK_CONDITION:
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106
				switch (check_sense(SCpnt))
				  {
				  case 0: 
				    update_timeout(SCpnt, oldto);
				    status = REDO;
				    break;
				  case SUGGEST_REMAP:			
				  case SUGGEST_RETRY:
				    status = MAYREDO;
				    exit = DRIVER_SENSE | SUGGEST_RETRY;
				    break;
				  case SUGGEST_ABORT:
				    status = FINISHED;
				    exit =  DRIVER_SENSE | SUGGEST_ABORT;
				    break;
				  case SUGGEST_SENSE:
1107
				scsi_request_sense (SCpnt);
1108
				status = PENDING;
1109
				break;       	
1110 1111
				  }
				break;       	
1112 1113 1114 1115 1116 1117 1118
			
			case CONDITION_GOOD:
			case INTERMEDIATE_GOOD:
			case INTERMEDIATE_C_GOOD:
				break;
				
			case BUSY:
1119
				update_timeout(SCpnt, oldto);
1120 1121 1122 1123
				status = REDO;
				break;

			case RESERVATION_CONFLICT:
1124
				printk("scsi%d : RESERVATION CONFLICT performing reset.\n", 
Linus Torvalds's avatar
Linus Torvalds committed
1125
					SCpnt->host->host_no);
1126
				reset(SCpnt);
1127 1128
				return;
#if 0
1129 1130 1131
				exit = DRIVER_SOFT | SUGGEST_ABORT;
				status = MAYREDO;
				break;
1132
#endif
1133
			default:
1134
				printk ("Internal error %s %d \n"
1135 1136 1137 1138 1139 1140
					"status byte = %d \n", __FILE__, 
					__LINE__, status_byte(result));
				
			}
			break;
			default:
Linus Torvalds's avatar
Linus Torvalds committed
1141
				panic("scsi: unsupported message byte %d recieved\n", msg_byte(result)); 
1142 1143 1144 1145 1146 1147 1148
			}
			break;
	case DID_TIME_OUT:	
#ifdef DEBUG
	printk("Host returned DID_TIME_OUT - ");
#endif

1149
		if (SCpnt->flags & WAS_TIMEDOUT)	
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
			{
#ifdef DEBUG
	printk("Aborting\n");
#endif	
			exit = (DRIVER_TIMEOUT | SUGGEST_ABORT);
			}		
		else 
			{
#ifdef DEBUG
			printk ("Retrying.\n");
#endif
1161
			SCpnt->flags  |= WAS_TIMEDOUT;
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
			status = REDO;
			}
		break;
	case DID_BUS_BUSY:
	case DID_PARITY:
		status = REDO;
		break;
	case DID_NO_CONNECT:
#ifdef DEBUG
		printk("Couldn't connect.\n");
#endif
		exit  = (DRIVER_HARD | SUGGEST_ABORT);
		break;
	case DID_ERROR:	
		status = MAYREDO;
		exit = (DRIVER_HARD | SUGGEST_ABORT);
		break;
	case DID_BAD_TARGET:
	case DID_ABORT:
		exit = (DRIVER_INVALID | SUGGEST_ABORT);
		break;	
1183 1184 1185
        case DID_RESET:
                if(msg_byte(result) == GOOD &&
                      status_byte(result) == CHECK_CONDITION) {
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200
			switch (check_sense(SCpnt)) {
			case 0: 
			    update_timeout(SCpnt, oldto);
			    status = REDO;
			    break;
			case SUGGEST_REMAP:			
			case SUGGEST_RETRY:
			    status = MAYREDO;
			    exit = DRIVER_SENSE | SUGGEST_RETRY;
			    break;
			case SUGGEST_ABORT:
			    status = FINISHED;
			    exit =  DRIVER_SENSE | SUGGEST_ABORT;
			    break;
			case SUGGEST_SENSE:
1201 1202 1203
                              scsi_request_sense (SCpnt);
                              status = PENDING;
                              break;
1204 1205
			}
		} else {
1206 1207
                status=REDO;
                exit = SUGGEST_RETRY;
1208
		}
1209
                break;
1210 1211 1212 1213 1214 1215 1216
	default : 		
		exit = (DRIVER_ERROR | SUGGEST_DIE);
	}

	switch (status) 
		{
		case FINISHED:
1217
		case PENDING:
1218 1219 1220 1221
			break;
		case MAYREDO:

#ifdef DEBUG
1222
	printk("In MAYREDO, allowing %d retries, have %d\n",
1223
	       SCpnt->allowed, SCpnt->retries);
1224 1225
#endif

1226
			if ((++SCpnt->retries) < SCpnt->allowed)
1227
			{
1228 1229
			if ((SCpnt->retries >= (SCpnt->allowed >> 1))
			    && !(SCpnt->flags & WAS_RESET))
1230
			        {
1231
					printk("scsi%d : reseting for second half of retries.\n",
Linus Torvalds's avatar
Linus Torvalds committed
1232
						SCpnt->host->host_no);
1233
					reset(SCpnt);
1234 1235 1236
					break;
			        }

1237 1238 1239 1240 1241 1242 1243 1244 1245
			}
			else
				{
				status = FINISHED;
				break;
				}
			/* fall through to REDO */

		case REDO:
1246 1247
			if (SCpnt->flags & WAS_SENSE)			
				scsi_request_sense(SCpnt); 	
1248
			else	
1249 1250 1251 1252 1253 1254
			  {
			    memcpy ((void *) SCpnt->cmnd,
				    (void*) SCpnt->data_cmnd, 
				    sizeof(SCpnt->data_cmnd));
			    SCpnt->request_buffer = SCpnt->buffer;
			    SCpnt->request_bufflen = SCpnt->bufflen;
1255
			    SCpnt->use_sg = SCpnt->old_use_sg;
1256 1257
			    internal_cmnd (SCpnt);
			  };
1258 1259 1260 1261 1262 1263 1264 1265
			break;	
		default: 
			INTERNAL_ERROR;
		}

	if (status == FINISHED) 
		{
		#ifdef DEBUG
1266
			printk("Calling done function - at address %08x\n", SCpnt->done);
1267
		#endif
Linus Torvalds's avatar
Linus Torvalds committed
1268 1269
		host->host_busy--; /* Indicate that we are free */
		wake_up(&host->host_wait);
1270
		SCpnt->result = result | ((exit & 0xff) << 24);
1271
		SCpnt->use_sg = SCpnt->old_use_sg;
1272
		SCpnt->done (SCpnt);
1273 1274 1275 1276 1277 1278
		}


#undef FINISHED
#undef REDO
#undef MAYREDO
1279
#undef PENDING
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297
	}

/*
	The scsi_abort function interfaces with the abort() function of the host
	we are aborting, and causes the current command to not complete.  The 
	caller should deal with any error messages or status returned on the 
	next call.
	
	This will not be called rentrantly for a given host.
*/
	
/*
	Since we're nice guys and specified that abort() and reset()
	can be non-reentrant.  The internal_timeout flags are used for
	this.
*/


1298
int scsi_abort (Scsi_Cmnd * SCpnt, int why)
1299 1300
	{
	int temp, oldto;
Linus Torvalds's avatar
Linus Torvalds committed
1301
	struct Scsi_Host * host = SCpnt->host;
1302 1303 1304 1305
	
	while(1)	
		{
		cli();
1306
		if (SCpnt->internal_timeout & IN_ABORT) 
1307 1308
			{
			sti();
1309
			while (SCpnt->internal_timeout & IN_ABORT);
1310 1311 1312
			}
		else
			{	
1313 1314
			SCpnt->internal_timeout |= IN_ABORT;
			oldto = update_timeout(SCpnt, ABORT_TIMEOUT);
1315 1316 1317

			
			sti();
Linus Torvalds's avatar
Linus Torvalds committed
1318
			if (!host->host_busy || !host->hostt->abort(SCpnt, why))
1319 1320 1321 1322 1323
				temp =  0;
			else
				temp = 1;
			
			cli();
1324 1325
			SCpnt->internal_timeout &= ~IN_ABORT;
			update_timeout(SCpnt, oldto);
1326 1327 1328 1329 1330 1331
			sti();
			return temp;
			}
		}	
	}

1332
int scsi_reset (Scsi_Cmnd * SCpnt)
1333 1334
	{
	int temp, oldto;
1335
	Scsi_Cmnd * SCpnt1;
Linus Torvalds's avatar
Linus Torvalds committed
1336
	struct Scsi_Host * host = SCpnt->host;
1337
	
1338
#ifdef DEBUG
Linus Torvalds's avatar
Linus Torvalds committed
1339
	printk("Danger Will Robinson! - SCSI bus for host %d is being reset.\n",host->host_no);
1340
#endif
1341 1342
	while (1) {
		cli();	
1343
		if (SCpnt->internal_timeout & IN_RESET)
1344 1345
			{
			sti();
1346
			while (SCpnt->internal_timeout & IN_RESET);
1347 1348 1349
			}
		else
			{
1350 1351
			SCpnt->internal_timeout |= IN_RESET;
			oldto = update_timeout(SCpnt, RESET_TIMEOUT);	
1352
					
Linus Torvalds's avatar
Linus Torvalds committed
1353
			if (host->host_busy)
1354 1355
				{	
				sti();
Linus Torvalds's avatar
Linus Torvalds committed
1356
				SCpnt1 = host->host_queue;
1357 1358 1359 1360 1361 1362 1363
				while(SCpnt1) {
				  if ((SCpnt1->request.dev > 0) &&
				      !(SCpnt1->flags & IS_RESETTING) && 
				      !(SCpnt1->internal_timeout & IN_ABORT))
				    scsi_abort(SCpnt1, DID_RESET);
				  SCpnt1 = SCpnt1->next;
				};
1364

1365
				temp = host->hostt->reset(SCpnt);	
1366 1367 1368
				}				
			else
				{
Linus Torvalds's avatar
Linus Torvalds committed
1369
				host->host_busy++;
1370 1371
	
				sti();
1372
				temp = host->hostt->reset(SCpnt);
Linus Torvalds's avatar
Linus Torvalds committed
1373 1374
				host->last_reset = jiffies;
				host->host_busy--;
1375 1376 1377
				}
	
			cli();
1378 1379
			SCpnt->internal_timeout &= ~IN_RESET;
			update_timeout(SCpnt, oldto);
1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392
			sti();
			return temp;	
			}
		}
	}
			 

static void scsi_main_timeout(void)
	{
	/*
		We must not enter update_timeout with a timeout condition still pending.
	*/

Linus Torvalds's avatar
Linus Torvalds committed
1393 1394
	int timed_out;
	struct Scsi_Host * host;
1395
	Scsi_Cmnd * SCpnt = NULL;
1396 1397 1398 1399 1400 1401 1402 1403 1404

	do 	{	
		cli();

	/*
		Find all timers such that they have 0 or negative (shouldn't happen)
		time remaining on them.
	*/
			
1405
		timed_out = 0;
Linus Torvalds's avatar
Linus Torvalds committed
1406 1407
		for(host = scsi_hostlist; host; host = host->next) {
		  SCpnt = host->host_queue;
1408
		  while (SCpnt){
1409
		    if (SCpnt->timeout > 0 && SCpnt->timeout <= time_elapsed)
1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421
		      {
			sti();
			SCpnt->timeout = 0;
			scsi_times_out(SCpnt);
			++timed_out; 
			cli();
		      }
		  SCpnt =  SCpnt->next;
		  };
		};
		update_timeout(NULL, 0);
	      } while (timed_out);	
1422
	sti();
1423
      }
1424 1425 1426 1427

/*
	The strategy is to cause the timer code to call scsi_times_out()
	when the soonest timeout is pending.  
1428 1429 1430
	The arguments are used when we are queueing a new command, because
	we do not want to subtract the time used from this time, but when we
	set the timer, we want to take this value into account.
1431 1432
*/
	
1433
static int update_timeout(Scsi_Cmnd * SCset, int timeout)
1434
	{
Linus Torvalds's avatar
Linus Torvalds committed
1435
	unsigned int least, used;
1436
	unsigned int oldto;
Linus Torvalds's avatar
Linus Torvalds committed
1437
	struct Scsi_Host * host;
1438
	Scsi_Cmnd * SCpnt = NULL;
1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453

	cli();

/* 
	Figure out how much time has passed since the last time the timeouts 
   	were updated 
*/
	used = (time_start) ? (jiffies - time_start) : 0;

/*
	Find out what is due to timeout soonest, and adjust all timeouts for
	the amount of time that has passed since the last time we called 
	update_timeout. 
*/
	
1454 1455 1456 1457 1458 1459 1460 1461 1462
	oldto = 0;

	if(SCset){
	  oldto = SCset->timeout - used;
	  SCset->timeout = timeout + used;
	};

	least = 0xffffffff;

Linus Torvalds's avatar
Linus Torvalds committed
1463 1464
	for(host = scsi_hostlist; host; host = host->next) {
	  SCpnt = host->host_queue;
1465 1466 1467 1468 1469 1470
	  while (SCpnt){
	    if (SCpnt->timeout > 0 && (SCpnt->timeout -= used) < least)
	      least = SCpnt->timeout;
	    SCpnt =  SCpnt->next;
	  };
	};
1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488

/*
	If something is due to timeout again, then we will set the next timeout 
	interrupt to occur.  Otherwise, timeouts are disabled.
*/
	
	if (least != 0xffffffff)
		{
		time_start = jiffies;	
		timer_table[SCSI_TIMER].expires = (time_elapsed = least) + jiffies;	
		timer_active |= 1 << SCSI_TIMER;
		}
	else
		{
		timer_table[SCSI_TIMER].expires = time_start = time_elapsed = 0;
		timer_active &= ~(1 << SCSI_TIMER);
		}	
	sti();
1489
	return oldto;
1490
	}		
1491 1492 1493 1494 1495 1496 1497 1498


static unsigned short * dma_malloc_freelist = NULL;
static unsigned int dma_sectors = 0;
unsigned int dma_free_sectors = 0;
unsigned int need_isa_buffer = 0;
static unsigned char * dma_malloc_buffer = NULL;

1499
void *scsi_malloc(unsigned int len)
1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518
{
  unsigned int nbits, mask;
  int i, j;
  if((len & 0x1ff) || len > 4096)
    panic("Inappropriate buffer size requested");
  
  cli();
  nbits = len >> 9;
  mask = (1 << nbits) - 1;
  
  for(i=0;i < (dma_sectors >> 4); i++)
    for(j=0; j<17-nbits; j++){
      if ((dma_malloc_freelist[i] & (mask << j)) == 0){
	dma_malloc_freelist[i] |= (mask << j);
	sti();
	dma_free_sectors -= nbits;
#ifdef DEBUG
	printk("SMalloc: %d %x ",len, dma_malloc_buffer + (i << 13) + (j << 9));
#endif
1519
	return (void *) ((unsigned long) dma_malloc_buffer + (i << 13) + (j << 9));
1520 1521 1522 1523 1524 1525
      };
    };
  sti();
  return NULL;  /* Nope.  No more */
}

1526
int scsi_free(void *obj, unsigned int len)
1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557
{
  int offset;
  int page, sector, nbits, mask;

#ifdef DEBUG
  printk("Sfree %x %d\n",obj, len);
#endif

  offset = ((int) obj) - ((int) dma_malloc_buffer);

  if (offset < 0) panic("Bad offset");
  page = offset >> 13;
  sector = offset >> 9;
  if(sector >= dma_sectors) panic ("Bad page");

  sector = (offset >> 9) & 15;
  nbits = len >> 9;
  mask = (1 << nbits) - 1;

  if ((mask << sector) > 0xffff) panic ("Bad memory alignment");

  cli();
  if(dma_malloc_freelist[page] & (mask << sector) != (mask<<sector))
    panic("Trying to free unused memory");

  dma_free_sectors += nbits;
  dma_malloc_freelist[page] &= ~(mask << sector);
  sti();
  return 0;
}

1558 1559 1560 1561 1562 1563
/*
	scsi_dev_init() is our initialization routine, which inturn calls host 
	initialization, bus scanning, and sd/st initialization routines.  It 
	should be called from main().
*/

1564
unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end)
1565 1566
	{
	int i;
Linus Torvalds's avatar
Linus Torvalds committed
1567
	struct Scsi_Host * host;
1568
	Scsi_Cmnd * SCpnt;
1569 1570 1571 1572 1573 1574
#ifdef FOO_ON_YOU
	return;
#endif	
	timer_table[SCSI_TIMER].fn = scsi_main_timeout;
	timer_table[SCSI_TIMER].expires = 0;

Linus Torvalds's avatar
Linus Torvalds committed
1575 1576
	/* initialize all hosts */
	memory_start = scsi_init(memory_start, memory_end); 
1577
				
1578
	scsi_devices = (Scsi_Device *) memory_start;
1579
        scan_scsis();           /* scan for scsi devices */
1580 1581 1582 1583 1584
	memory_start += NR_SCSI_DEVICES * sizeof(Scsi_Device);

	memory_start = sd_init1(memory_start, memory_end);
        memory_start = st_init1(memory_start, memory_end);
	memory_start = sr_init1(memory_start, memory_end);
Linus Torvalds's avatar
Linus Torvalds committed
1585
	memory_start = sg_init1(memory_start, memory_end);
1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601

	last_cmnd = (Scsi_Cmnd *) memory_start;

	SCpnt = last_cmnd;

	for (i=0; i< NR_SCSI_DEVICES; i++) {
	  int j;
	  switch (scsi_devices[i].type)
	    {
	    case TYPE_TAPE :
	      st_attach(&scsi_devices[i]);
	      break;
	    case TYPE_ROM:
	      sr_attach(&scsi_devices[i]);
	      break;
	    case TYPE_DISK:
1602
	    case TYPE_MOD:
1603 1604 1605 1606
	      sd_attach(&scsi_devices[i]);
	    default:
	      break;
	    };
Linus Torvalds's avatar
Linus Torvalds committed
1607
	  sg_attach(&scsi_devices[i]);
1608
	  if(scsi_devices[i].type != -1){
Linus Torvalds's avatar
Linus Torvalds committed
1609 1610
	    for(j=0;j<scsi_devices[i].host->hostt->cmd_per_lun;j++){
	      SCpnt->host = scsi_devices[i].host;
1611 1612 1613 1614 1615
	      SCpnt->target = scsi_devices[i].id;
	      SCpnt->lun = scsi_devices[i].lun;
	      SCpnt->index = i;
	      SCpnt->request.dev = -1; /* Mark not busy */
	      SCpnt->use_sg = 0;
1616
	      SCpnt->old_use_sg = 0;
1617 1618
              SCpnt->underflow = 0;
              SCpnt->transfersize = 0;
1619
	      SCpnt->host_scribble = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
1620 1621 1622 1623
	      host = scsi_devices[i].host;
	      if(host->host_queue)
		host->host_queue->prev = SCpnt;
	      SCpnt->next = host->host_queue;
1624
	      SCpnt->prev = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
1625
	      host->host_queue = SCpnt;
1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636
	      SCpnt++;
	    };
	  };
	};

	memory_start = (int) SCpnt;

	if (NR_SD > 0 || NR_SR > 0 || NR_ST > 0)
	  dma_sectors = 16;  /* Base value we use */

	for (i = 0; i < NR_SCSI_DEVICES; ++i) {
Linus Torvalds's avatar
Linus Torvalds committed
1637 1638
	  struct Scsi_Host * host;
	  host = scsi_devices[i].host;
1639 1640
	  
	  if(scsi_devices[i].type != TYPE_TAPE)
Linus Torvalds's avatar
Linus Torvalds committed
1641
	    dma_sectors += ((host->sg_tablesize * 
1642
			     sizeof(struct scatterlist) + 511) >> 9) * 
Linus Torvalds's avatar
Linus Torvalds committed
1643
			       host->hostt->cmd_per_lun;
1644
	  
Linus Torvalds's avatar
Linus Torvalds committed
1645
	  if(host->unchecked_isa_dma &&
1646 1647
	     memory_end > ISA_DMA_THRESHOLD &&
	     scsi_devices[i].type != TYPE_TAPE) {
Linus Torvalds's avatar
Linus Torvalds committed
1648 1649
	    dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize *
	      host->hostt->cmd_per_lun;
1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663
	    need_isa_buffer++;
	  };
	};

	dma_sectors = (dma_sectors + 15) & 0xfff0;
	dma_free_sectors = dma_sectors;  /* This must be a multiple of 16 */

	memory_start = (memory_start + 3) & 0xfffffffc;
	dma_malloc_freelist = (unsigned short *) memory_start;
	memory_start += dma_sectors >> 3;
	memset(dma_malloc_freelist, 0, dma_sectors >> 3);

	if(memory_start & 1) memory_start++; /* Some host adapters require
						buffers to be word aligned */
1664
	dma_malloc_buffer = (unsigned char *) memory_start;
1665 1666 1667 1668
	memory_start += dma_sectors << 9;

	memory_start = sd_init(memory_start, memory_end); /* init scsi disks */
        memory_start = st_init(memory_start, memory_end); /* init scsi tapes */
Linus Torvalds's avatar
Linus Torvalds committed
1669 1670 1671
	memory_start = sr_init(memory_start, memory_end); /* init scsi CDROMs */
	memory_start = sg_init(memory_start, memory_end); /* init scsi generic */
	
1672
	return memory_start;
1673
	}
1674 1675 1676 1677 1678

static void print_inquiry(unsigned char *data)
{
        int i;

1679 1680
	printk("  Vendor: ");
	for (i = 8; i < 16; i++)
1681
	        {
Linus Torvalds's avatar
Linus Torvalds committed
1682
	        if (data[i] >= 0x20 && i < data[4] + 5)
1683 1684 1685 1686 1687
		        printk("%c", data[i]);
	        else
		        printk(" ");
	        }

1688 1689
	printk("  Model: ");
	for (i = 16; i < 32; i++)
1690
	        {
Linus Torvalds's avatar
Linus Torvalds committed
1691
	        if (data[i] >= 0x20 && i < data[4] + 5)
1692 1693 1694 1695 1696
		        printk("%c", data[i]);
	        else
		        printk(" ");
	        }

1697 1698
	printk("  Rev: ");
	for (i = 32; i < 36; i++)
1699
	        {
Linus Torvalds's avatar
Linus Torvalds committed
1700
	        if (data[i] >= 0x20 && i < data[4] + 5)
1701 1702 1703 1704 1705 1706 1707 1708 1709
		        printk("%c", data[i]);
	        else
		        printk(" ");
	        }

	printk("\n");

	i = data[0] & 0x1f;

Linus Torvalds's avatar
Linus Torvalds committed
1710 1711
	printk("  Type:   %s ",
	       i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : "Unknown          " );
1712 1713 1714 1715 1716
	printk("                 ANSI SCSI revision: %02x", data[2] & 0x07);
	if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1)
	  printk(" CCS\n");
	else
	  printk("\n");
1717
}