patch-1.3.5 linux/drivers/scsi/eata.c

Next file: linux/drivers/scsi/eata.h
Previous file: linux/drivers/scsi/constants.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.4/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c
@@ -198,14 +198,14 @@
    ulong  data_len;     /* Number of valid bytes after this field */
    ulong  sign;         /* ASCII "EATA" signature */
    unchar        :4,    /* unused low nibble */
-          version:4;    /* EATA version, should be 0x1 */
+	  version:4;    /* EATA version, should be 0x1 */
    unchar  ocsena:1,    /* Overlap Command Support Enabled */
-           tarsup:1,    /* Target Mode Supported */
-                 :2,
-           dmasup:1,    /* DMA Supported */
-           drqvld:1,    /* DRQ Index (DRQX) is valid */
-              ata:1,    /* This is an ATA device */
-           haaval:1;    /* Host Adapter Address Valid */
+	   tarsup:1,    /* Target Mode Supported */
+		 :2,
+	   dmasup:1,    /* DMA Supported */
+	   drqvld:1,    /* DRQ Index (DRQX) is valid */
+	      ata:1,    /* This is an ATA device */
+	   haaval:1;    /* Host Adapter Address Valid */
    ushort cp_pad_len;   /* Number of pad bytes after cp_len */
    unchar host_addr[3]; /* Host Adapter SCSI ID for channels 2, 1, 0 */
    unchar reserved;
@@ -215,17 +215,17 @@
    ushort unused;
    ushort scatt_size;   /* Max number of entries in scatter/gather table */
    unchar     irq:4,    /* Interrupt Request assigned to this controller */
-           irq_tr:1,    /* 0 for edge triggered, 1 for level triggered */
-           second:1,    /* 1 if this is a secondary (not primary) controller */
-             drqx:2;    /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
+	   irq_tr:1,    /* 0 for edge triggered, 1 for level triggered */
+	   second:1,    /* 1 if this is a secondary (not primary) controller */
+	     drqx:2;    /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
    unchar  sync;        /* 1 if scsi target id 7...0 is running sync scsi */
 
    /* Structure extension defined in EATA 2.0B */
    unchar  isaena:1,    /* ISA i/o addressing is disabled/enabled */
-         forcaddr:1,    /* Port address has been forced */
-                 :6;
+	 forcaddr:1,    /* Port address has been forced */
+		 :6;
    unchar  max_id:5,    /* Max number of SCSI target IDs */
-         max_chan:3;    /* Max SCSI channel number on this board */
+	 max_chan:3;    /* Max SCSI channel number on this board */
 
    ushort ipad[249];
    };
@@ -234,17 +234,17 @@
 struct eata_config {
    ushort len;          /* Number of bytes following this field */
    unchar edis:1,       /* Disable EATA interface after config command */
-         ocena:1,       /* Overlapped Commands Enabled */
-        mdpena:1,       /* Transfer all Modified Data Pointer Messages */
-        tarena:1,       /* Target Mode Enabled for this controller */
-              :4;
+	 ocena:1,       /* Overlapped Commands Enabled */
+	mdpena:1,       /* Transfer all Modified Data Pointer Messages */
+	tarena:1,       /* Target Mode Enabled for this controller */
+	      :4;
    unchar cpad[511];
    };
 
 /* Returned status packet structure */
 struct mssp {
    unchar adapter_status:7,    /* State related to current command */
-                     eoc:1;    /* End Of Command (1 = command completed) */
+		     eoc:1;    /* End Of Command (1 = command completed) */
    unchar target_status;       /* SCSI status received after data transfer */
    unchar unused[2];
    ulong inv_res_len;          /* Number of bytes not transferred */
@@ -255,23 +255,23 @@
 /* MailBox SCSI Command Packet */
 struct mscp {
    unchar  sreset:1,     /* SCSI Bus Reset Signal should be asserted */
-             init:1,     /* Re-initialize controller and self test */
-           reqsen:1,     /* Transfer Request Sense Data to addr using DMA */
-               sg:1,     /* Use Scatter/Gather */
-                 :1,
-           interp:1,     /* The controller interprets cp, not the target */ 
-             dout:1,     /* Direction of Transfer is Out (Host to Target) */
-              din:1;     /* Direction of Transfer is In (Target to Host) */
+	     init:1,     /* Re-initialize controller and self test */
+	   reqsen:1,     /* Transfer Request Sense Data to addr using DMA */
+	       sg:1,     /* Use Scatter/Gather */
+		 :1,
+	   interp:1,     /* The controller interprets cp, not the target */ 
+	     dout:1,     /* Direction of Transfer is Out (Host to Target) */
+	      din:1;     /* Direction of Transfer is In (Target to Host) */
    unchar sense_len;     /* Request Sense Length */
    unchar unused[4];
    unchar phsunit:1,     /* Send to Target Physical Unit (bypass RAID) */
-          notused:7;
+	  notused:7;
    unchar target;        /* SCSI Target ID */
    unchar     lun:3,     /* LUN */
-                 :2,
-           luntar:1,     /* This cp is for Target (not LUN) */
-           dispri:1,     /* Disconnect Privilege granted */
-              one:1;     /* 1 */
+		 :2,
+	   luntar:1,     /* This cp is for Target (not LUN) */
+	   dispri:1,     /* Disconnect Privilege granted */
+	      one:1;     /* 1 */
    unchar mess[3];       /* Massage to/from Target */
    unchar cdb[12];       /* Command Descriptor Block */
    ulong  data_len;      /* If sg=0 Data Length, if sg=1 sglist length */
@@ -346,7 +346,7 @@
    for (p = start; p <= end; p++) {
 
       while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) 
-         if (--loop == 0) return TRUE;
+	 if (--loop == 0) return TRUE;
 
       loop = MAXLOOP;
       *p = inw(iobase);
@@ -356,7 +356,7 @@
 }
 
 static inline int port_detect(ushort *port_base, unsigned int j, 
-                              Scsi_Host_Template * tpnt) {
+			      Scsi_Host_Template * tpnt) {
    unsigned char irq, dma_channel, subversion;
    unsigned char protocol_rev;
    struct eata_info info;
@@ -371,7 +371,7 @@
 
    if(check_region(*port_base, REGION_SIZE)) {
       printk("%s: address 0x%03x in use, skipping probe.\n", 
-             name, *port_base);
+	     name, *port_base);
       return FALSE;
       }
 
@@ -386,7 +386,7 @@
 
    if (ntohl(info.data_len) < EATA_2_0A_SIZE) {
       printk("%s: config structure size (%ld bytes) too short, detaching.\n", 
-             name, ntohl(info.data_len));
+	     name, ntohl(info.data_len));
       return FALSE;
       }
    else if (ntohl(info.data_len) == EATA_2_0A_SIZE)
@@ -404,10 +404,10 @@
    if (*port_base & EISA_RANGE) {
 
       if (!info.haaval || info.ata || info.drqvld) {
-         printk("%s: unusable EISA board found (%d%d%d), detaching.\n", 
-                name, info.haaval, info.ata, info.drqvld);
-         return FALSE;
-         }
+	 printk("%s: unusable EISA board found (%d%d%d), detaching.\n", 
+		name, info.haaval, info.ata, info.drqvld);
+	 return FALSE;
+	 }
 
       subversion = ESA;
       dma_channel = NO_DMA;
@@ -415,10 +415,10 @@
    else {
 
       if (!info.haaval || info.ata || !info.drqvld) {
-         printk("%s: unusable ISA board found (%d%d%d), detaching.\n",
-                name, info.haaval, info.ata, info.drqvld);
-         return FALSE;
-         }
+	 printk("%s: unusable ISA board found (%d%d%d), detaching.\n",
+		name, info.haaval, info.ata, info.drqvld);
+	 return FALSE;
+	 }
 
       subversion = ISA;
       dma_channel = dma_channel_table[3 - info.drqx];
@@ -429,7 +429,7 @@
 
    if (subversion == ESA && !info.irq_tr)
       printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
-             name, irq);
+	     name, irq);
 
    if (info.second)
       board_status = "Sec.";
@@ -445,7 +445,7 @@
 
    if (subversion == ISA && request_dma(dma_channel, driver_name)) {
       printk("%s: unable to allocate DMA channel %u, detaching.\n",
-             name, dma_channel);
+	     name, dma_channel);
       free_irq(irq);
       return FALSE;
       }
@@ -510,9 +510,9 @@
    strcpy(BN(j), name);
 
    printk("%s: 2.0%c, %s, ID %d, PORT 0x%03x, IRQ %u, DMA %u, SG %d, "\
-          "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev, board_status, 
-           sh[j]->this_id, sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
-           sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun);
+	  "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev, board_status, 
+	   sh[j]->this_id, sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
+	   sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun);
 
    /* DPT PM2012 does not allow to detect sg_tablesize correctly */
    if (sh[j]->sg_tablesize > MAX_SGLIST || sh[j]->sg_tablesize < 2) {
@@ -529,12 +529,12 @@
 #if defined (DEBUG_DETECT)
    if (protocol_rev != 'A')
       printk("%s: EATA 2.0%c, isaena %u, forcaddr %u, max_id %u,"\
-             " max_chan %u.\n", name, protocol_rev, info.isaena, 
-             info.forcaddr, info.max_id, info.max_chan);
+	     " max_chan %u.\n", name, protocol_rev, info.isaena, 
+	     info.forcaddr, info.max_id, info.max_chan);
 
    printk("%s: Version 0x%x, SYNC 0x%x, infol %ld, cpl %ld spl %ld.\n", 
-          name, info.version, info.sync, ntohl(info.data_len), 
-          ntohl(info.cp_len), ntohl(info.sp_len));
+	  name, info.version, info.sync, ntohl(info.data_len), 
+	  ntohl(info.cp_len), ntohl(info.sp_len));
 #endif
 
    return TRUE;
@@ -617,18 +617,18 @@
       if (i >= sh[j]->can_queue) i = 0;
 
       if (HD(j)->cp_stat[i] == FREE) {
-         HD(j)->last_cp_used = i;
-         break;
-         }
+	 HD(j)->last_cp_used = i;
+	 break;
+	 }
       }
 
    if (k == sh[j]->can_queue) {
       printk("%s: qcomm, no free mailbox, resetting.\n", BN(j));
 
       if (HD(j)->in_reset) 
-         printk("%s: qcomm, already in reset.\n", BN(j));
+	 printk("%s: qcomm, already in reset.\n", BN(j));
       else if (eata2x_reset(SCpnt) == SCSI_RESET_SUCCESS) 
-         panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j));
+	 panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j));
 
       SCpnt->result = DID_BUS_BUSY << 16; 
       SCpnt->host_scribble = NULL;
@@ -656,13 +656,13 @@
    SCpnt->host_scribble = (unsigned char *) &cpp->index;
 
    if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
-                        BN(j), i, SCpnt->target, SCpnt->pid);
+			BN(j), i, SCpnt->target, SCpnt->pid);
 
    for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
      if (SCpnt->cmnd[0] == data_out_cmds[k]) {
-        cpp->dout = TRUE;
-        break;
-        }
+	cpp->dout = TRUE;
+	break;
+	}
 
    cpp->din = !cpp->dout;
    cpp->reqsen = TRUE;
@@ -690,7 +690,7 @@
       SCpnt->result = DID_ERROR << 16; 
       SCpnt->host_scribble = NULL;
       printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n", 
-             BN(j), SCpnt->target, SCpnt->pid);
+	     BN(j), SCpnt->target, SCpnt->pid);
       restore_flags(flags);
       done(SCpnt);    
       return 0;
@@ -710,13 +710,13 @@
 
    if (SCarg->host_scribble == NULL) {
       printk("%s: abort, target %d, pid %ld inactive.\n",
-             BN(j), SCarg->target, SCarg->pid);
+	     BN(j), SCarg->target, SCarg->pid);
       return SCSI_ABORT_NOT_RUNNING;
       }
 
    i = *(unsigned int *)SCarg->host_scribble;
    printk("%s: abort, mbox %d, target %d, pid %ld.\n", 
-          BN(j), i, SCarg->target, SCarg->pid);
+	  BN(j), i, SCarg->target, SCarg->pid);
 
    if (i >= sh[j]->can_queue)
       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
@@ -737,8 +737,8 @@
       printk("%s: abort, mbox %d is in use.\n", BN(j), i);
 
       if (SCarg != HD(j)->cp[i].SCpnt)
-         panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
-               BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
+	 panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
+	       BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
 
       restore_flags(flags);
       return SCSI_ABORT_SNOOZE;
@@ -768,7 +768,7 @@
    cli();
    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
    printk("%s: reset, enter, target %d, pid %ld.\n", 
-          BN(j), SCarg->target, SCarg->pid);
+	  BN(j), SCarg->target, SCarg->pid);
 
    if (SCarg->host_scribble == NULL)
       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
@@ -794,27 +794,27 @@
       if (HD(j)->cp_stat[i] == FREE) continue;
 
       if (HD(j)->cp_stat[i] == LOCKED) {
-         HD(j)->cp_stat[i] = FREE;
-         printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
-         continue;
-         }
+	 HD(j)->cp_stat[i] = FREE;
+	 printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
+	 continue;
+	 }
 
       SCpnt = HD(j)->cp[i].SCpnt;
       HD(j)->cp_stat[i] = IN_RESET;
       printk("%s: reset, mbox %d in reset, pid %ld.\n",
-             BN(j), i, SCpnt->pid);
+	     BN(j), i, SCpnt->pid);
 
       if (SCpnt == NULL)
-         panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
+	 panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
 
       if (SCpnt->host_scribble == NULL)
-         panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
+	 panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
 
       if (*(unsigned int *)SCpnt->host_scribble != i) 
-         panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
+	 panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
 
       if (SCpnt->scsi_done == NULL) 
-         panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
+	 panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
 
       if (SCpnt == SCarg) arg_done = TRUE;
       }
@@ -851,7 +851,7 @@
       HD(j)->cp_stat[i] = LOCKED;
 
       printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
-             BN(j), i, SCpnt->pid);
+	     BN(j), i, SCpnt->pid);
       restore_flags(flags);
       SCpnt->scsi_done(SCpnt);
       cli();
@@ -887,7 +887,7 @@
       }
 
    if (do_trace) printk("%s: ihdlr, enter, irq %d, calls %d.\n", 
-                        driver_name, irq, calls[irq]);
+			driver_name, irq, calls[irq]);
 
    /* Service all the boards configured on this irq */
    for (j = 0; sh[j] != NULL; j++) {
@@ -898,164 +898,164 @@
 
       /* Loop until all interrupts for a board are serviced */
       while (inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED) {
-         total_loops++;
-         loops++;
+	 total_loops++;
+	 loops++;
 
-         if (do_trace) printk("%s: ihdlr, start service, count %d.\n",
-                              BN(j), HD(j)->iocount);
+	 if (do_trace) printk("%s: ihdlr, start service, count %d.\n",
+			      BN(j), HD(j)->iocount);
    
-         /* Read the status register to clear the interrupt indication */
-         inb(sh[j]->io_port + REG_STATUS);
+	 /* Read the status register to clear the interrupt indication */
+	 inb(sh[j]->io_port + REG_STATUS);
    
-         /* Service all mailboxes of this board */
-         for (i = 0; i < sh[j]->can_queue; i++) {
-            spp = &HD(j)->sp[i];
-   
-            /* Check if this mailbox has completed the operation */
-            if (spp->eoc == FALSE) continue;
-   
-            spp->eoc = FALSE;
-   
-            if (HD(j)->cp_stat[i] == IGNORE) {
-               HD(j)->cp_stat[i] = FREE;
-               continue;
-               }
-            else if (HD(j)->cp_stat[i] == LOCKED) {
-               HD(j)->cp_stat[i] = FREE;
-               printk("%s: ihdlr, mbox %d unlocked, count %d.\n",
-                      BN(j), i, HD(j)->iocount);
-               continue;
-               }
-            else if (HD(j)->cp_stat[i] == FREE) {
-               printk("%s: ihdlr, mbox %d is free, count %d.\n", 
-                      BN(j), i, HD(j)->iocount);
-               continue;
-               }
-            else if (HD(j)->cp_stat[i] == IN_RESET)
-               printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
-            else if (HD(j)->cp_stat[i] != IN_USE) 
-               panic("%s: ihdlr, mbox %d, invalid cp_stat.\n", BN(j), i);
-   
-            HD(j)->cp_stat[i] = FREE;
-            cpp = &HD(j)->cp[i];
-            SCpnt = spp->SCpnt;
-   
-            if (SCpnt == NULL)
-               panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
-   
-            if (SCpnt != cpp->SCpnt)
-               panic("%s: ihdlr, mbox %d, sp SCpnt %p, cp SCpnt %p.\n",
-                     BN(j), i, SCpnt, cpp->SCpnt);
-   
-            if (SCpnt->host_scribble == NULL)
-               panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n",
-                     BN(j), i, SCpnt->pid, SCpnt);
-   
-            if (*(unsigned int *)SCpnt->host_scribble != i) 
-               panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d,"\
-                     " irq %d.\n", BN(j), i, SCpnt->pid, 
-                     *(unsigned int *)SCpnt->host_scribble, irq);
-   
-            tstatus = status_byte(spp->target_status);
-   
-            switch (spp->adapter_status) {
-               case ASOK:     /* status OK */
-   
-                  /* Forces a reset if a disk drive keeps returning BUSY */
-                  if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE) 
-                     status = DID_ERROR << 16;
-   
-                  /* If there was a bus reset, redo operation on each target */
-                  else if (tstatus != GOOD
-                           && SCpnt->device->type == TYPE_DISK
-                           && HD(j)->target_reset[SCpnt->target])
-                     status = DID_BUS_BUSY << 16;
-   
-                  /* Works around a flaw in scsi.c */
-                  else if (tstatus == CHECK_CONDITION
-                           && SCpnt->device->type == TYPE_DISK
-                           && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
-                     status = DID_BUS_BUSY << 16;
-
-                  else
-                     status = DID_OK << 16;
-   
-                  if (tstatus == GOOD)
-                     HD(j)->target_reset[SCpnt->target] = FALSE;
-   
-                  if (spp->target_status && SCpnt->device->type == TYPE_DISK)
-                     printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
-                            "0x%x, sense key 0x%x.\n", BN(j), 
-                            SCpnt->target, SCpnt->lun, SCpnt->pid,
-                            spp->target_status, SCpnt->sense_buffer[2]);
-   
-                  HD(j)->target_time_out[SCpnt->target] = 0;
-   
-                  break;
-               case ASST:     /* Selection Time Out */
-               case 0x02:     /* Command Time Out   */
-   
-                  if (HD(j)->target_time_out[SCpnt->target] > 1)
-                     status = DID_ERROR << 16;
-                  else {
-                     status = DID_TIME_OUT << 16;
-                     HD(j)->target_time_out[SCpnt->target]++;
-                     }
-   
-                  break;
-               case 0x03:     /* SCSI Bus Reset Received */
-               case 0x04:     /* Initial Controller Power-up */
-   
-                  if (SCpnt->device->type != TYPE_TAPE)
-                     status = DID_BUS_BUSY << 16;
-                  else
-                     status = DID_ERROR << 16;
-   
-                  for (k = 0; k < MAX_TARGET; k++) 
-                     HD(j)->target_reset[k] = TRUE;
-   
-                  break;
-               case 0x07:     /* Bus Parity Error */
-               case 0x0c:     /* Controller Ram Parity */
-               case 0x05:     /* Unexpected Bus Phase */
-               case 0x06:     /* Unexpected Bus Free */
-               case 0x08:     /* SCSI Hung */
-               case 0x09:     /* Unexpected Message Reject */
-               case 0x0a:     /* SCSI Bus Reset Stuck */
-               case 0x0b:     /* Auto Request-Sense Failed */
-               default:
-                  status = DID_ERROR << 16;
-                  break;
-               }
+	 /* Service all mailboxes of this board */
+	 for (i = 0; i < sh[j]->can_queue; i++) {
+	    spp = &HD(j)->sp[i];
+   
+	    /* Check if this mailbox has completed the operation */
+	    if (spp->eoc == FALSE) continue;
+   
+	    spp->eoc = FALSE;
+   
+	    if (HD(j)->cp_stat[i] == IGNORE) {
+	       HD(j)->cp_stat[i] = FREE;
+	       continue;
+	       }
+	    else if (HD(j)->cp_stat[i] == LOCKED) {
+	       HD(j)->cp_stat[i] = FREE;
+	       printk("%s: ihdlr, mbox %d unlocked, count %d.\n",
+		      BN(j), i, HD(j)->iocount);
+	       continue;
+	       }
+	    else if (HD(j)->cp_stat[i] == FREE) {
+	       printk("%s: ihdlr, mbox %d is free, count %d.\n", 
+		      BN(j), i, HD(j)->iocount);
+	       continue;
+	       }
+	    else if (HD(j)->cp_stat[i] == IN_RESET)
+	       printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
+	    else if (HD(j)->cp_stat[i] != IN_USE) 
+	       panic("%s: ihdlr, mbox %d, invalid cp_stat.\n", BN(j), i);
+   
+	    HD(j)->cp_stat[i] = FREE;
+	    cpp = &HD(j)->cp[i];
+	    SCpnt = spp->SCpnt;
+   
+	    if (SCpnt == NULL)
+	       panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
+   
+	    if (SCpnt != cpp->SCpnt)
+	       panic("%s: ihdlr, mbox %d, sp SCpnt %p, cp SCpnt %p.\n",
+		     BN(j), i, SCpnt, cpp->SCpnt);
+   
+	    if (SCpnt->host_scribble == NULL)
+	       panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n",
+		     BN(j), i, SCpnt->pid, SCpnt);
+   
+	    if (*(unsigned int *)SCpnt->host_scribble != i) 
+	       panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d,"\
+		     " irq %d.\n", BN(j), i, SCpnt->pid, 
+		     *(unsigned int *)SCpnt->host_scribble, irq);
+   
+	    tstatus = status_byte(spp->target_status);
+   
+	    switch (spp->adapter_status) {
+	       case ASOK:     /* status OK */
+   
+		  /* Forces a reset if a disk drive keeps returning BUSY */
+		  if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE) 
+		     status = DID_ERROR << 16;
+   
+		  /* If there was a bus reset, redo operation on each target */
+		  else if (tstatus != GOOD
+			   && SCpnt->device->type == TYPE_DISK
+			   && HD(j)->target_reset[SCpnt->target])
+		     status = DID_BUS_BUSY << 16;
+   
+		  /* Works around a flaw in scsi.c */
+		  else if (tstatus == CHECK_CONDITION
+			   && SCpnt->device->type == TYPE_DISK
+			   && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
+		     status = DID_BUS_BUSY << 16;
+
+		  else
+		     status = DID_OK << 16;
+   
+		  if (tstatus == GOOD)
+		     HD(j)->target_reset[SCpnt->target] = FALSE;
+   
+		  if (spp->target_status && SCpnt->device->type == TYPE_DISK)
+		     printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
+			    "0x%x, sense key 0x%x.\n", BN(j), 
+			    SCpnt->target, SCpnt->lun, SCpnt->pid,
+			    spp->target_status, SCpnt->sense_buffer[2]);
+   
+		  HD(j)->target_time_out[SCpnt->target] = 0;
+   
+		  break;
+	       case ASST:     /* Selection Time Out */
+	       case 0x02:     /* Command Time Out   */
+   
+		  if (HD(j)->target_time_out[SCpnt->target] > 1)
+		     status = DID_ERROR << 16;
+		  else {
+		     status = DID_TIME_OUT << 16;
+		     HD(j)->target_time_out[SCpnt->target]++;
+		     }
+   
+		  break;
+	       case 0x03:     /* SCSI Bus Reset Received */
+	       case 0x04:     /* Initial Controller Power-up */
+   
+		  if (SCpnt->device->type != TYPE_TAPE)
+		     status = DID_BUS_BUSY << 16;
+		  else
+		     status = DID_ERROR << 16;
+   
+		  for (k = 0; k < MAX_TARGET; k++) 
+		     HD(j)->target_reset[k] = TRUE;
+   
+		  break;
+	       case 0x07:     /* Bus Parity Error */
+	       case 0x0c:     /* Controller Ram Parity */
+	       case 0x05:     /* Unexpected Bus Phase */
+	       case 0x06:     /* Unexpected Bus Free */
+	       case 0x08:     /* SCSI Hung */
+	       case 0x09:     /* Unexpected Message Reject */
+	       case 0x0a:     /* SCSI Bus Reset Stuck */
+	       case 0x0b:     /* Auto Request-Sense Failed */
+	       default:
+		  status = DID_ERROR << 16;
+		  break;
+	       }
    
-            SCpnt->result = status | spp->target_status;
-            HD(j)->iocount++;
+	    SCpnt->result = status | spp->target_status;
+	    HD(j)->iocount++;
 
-            if (loops > 1) HD(j)->multicount++;
+	    if (loops > 1) HD(j)->multicount++;
 
 #if defined (DEBUG_INTERRUPT)
-            if (SCpnt->result || do_trace)
+	    if (SCpnt->result || do_trace)
 #else
-            if ((spp->adapter_status != ASOK && HD(j)->iocount >  1000) ||
-                (spp->adapter_status != ASOK && 
-                 spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
-                do_trace)
+	    if ((spp->adapter_status != ASOK && HD(j)->iocount >  1000) ||
+		(spp->adapter_status != ASOK && 
+		 spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
+		do_trace)
 #endif
-               printk("%s: ihdlr, mbox %d, err 0x%x:%x,"\
-                      " target %d:%d, pid %ld, count %d.\n",
-                      BN(j), i, spp->adapter_status, spp->target_status,
-                      SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
+	       printk("%s: ihdlr, mbox %d, err 0x%x:%x,"\
+		      " target %d:%d, pid %ld, count %d.\n",
+		      BN(j), i, spp->adapter_status, spp->target_status,
+		      SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
    
-            /* Set the command state to inactive */
-            SCpnt->host_scribble = NULL;
+	    /* Set the command state to inactive */
+	    SCpnt->host_scribble = NULL;
    
-            restore_flags(flags);
-            SCpnt->scsi_done(SCpnt);
-            cli();
+	    restore_flags(flags);
+	    SCpnt->scsi_done(SCpnt);
+	    cli();
 
-            }   /* Mailbox loop */
+	    }   /* Mailbox loop */
 
-         }   /* Multiple command loop */
+	 }   /* Multiple command loop */
 
       }   /* Boards loop */
 
@@ -1063,16 +1063,16 @@
 
    if (total_loops == 0) 
      printk("%s: ihdlr, irq %d, no command completed, calls %d.\n",
-            driver_name, irq, calls[irq]);
+	    driver_name, irq, calls[irq]);
 
    if (do_trace) printk("%s: ihdlr, exit, irq %d, calls %d.\n", 
-                        driver_name, irq, calls[irq]);
+			driver_name, irq, calls[irq]);
 
 #if defined (DEBUG_STATISTICS)
    if ((calls[irq] % 100000) == 10000)
       for (j = 0; sh[j] != NULL; j++)
-         printk("%s: ihdlr, calls %d, count %d, multi %d.\n", BN(j),
-                calls[(sh[j]->irq)], HD(j)->iocount, HD(j)->multicount);
+	 printk("%s: ihdlr, calls %d, count %d, multi %d.\n", BN(j),
+		calls[(sh[j]->irq)], HD(j)->iocount, HD(j)->multicount);
 #endif
 
    restore_flags(flags);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this