process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,			 struct Scsi_Host *host,			 struct NCR_700_Host_Parameters *hostdata){	__u32 resume_offset = 0;	__u8 pun = 0xff, lun=0xff;	if(SCp != NULL) {		pun = SCp->device->id;		lun = SCp->device->lun;	}	if(dsps == A_GOOD_STATUS_AFTER_STATUS) {		DEBUG(("  COMMAND COMPLETE, status=%02x\n",		       hostdata->status[0]));		/* OK, if TCQ still under negotiation, we now know it works */		if (NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION)			NCR_700_set_tag_neg_state(SCp->device,						  NCR_700_FINISHED_TAG_NEGOTIATION);					/* check for contingent allegiance contitions */		if(status_byte(hostdata->status[0]) == CHECK_CONDITION ||		   status_byte(hostdata->status[0]) == COMMAND_TERMINATED) {			struct NCR_700_command_slot *slot =				(struct NCR_700_command_slot *)SCp->host_scribble;			if(SCp->cmnd[0] == REQUEST_SENSE) {				/* OOPS: bad device, returning another				 * contingent allegiance condition */				printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun);				NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);			} else {#ifdef NCR_DEBUG				scsi_print_command(SCp);				printk("  cmd %p has status %d, requesting sense\n",				       SCp, hostdata->status[0]);#endif				/* we can destroy the command here				 * because the contingent allegiance				 * condition will cause a retry which				 * will re-copy the command from the				 * saved data_cmnd.  We also unmap any				 * data associated with the command				 * here */				NCR_700_unmap(hostdata, SCp, slot);				SCp->cmnd[0] = REQUEST_SENSE;				SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5;				SCp->cmnd[2] = 0;				SCp->cmnd[3] = 0;				SCp->cmnd[4] = sizeof(SCp->sense_buffer);				SCp->cmnd[5] = 0;				SCp->cmd_len = 6;				/* Here's a quiet hack: the				 * REQUEST_SENSE command is six bytes,				 * so store a flag indicating that				 * this was an internal sense request				 * and the original status at the end				 * of the command */				SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;				SCp->cmnd[7] = hostdata->status[0];				SCp->use_sg = 0;				SCp->sc_data_direction = DMA_FROM_DEVICE;				dma_sync_single_for_device(hostdata->dev, slot->pCmd,							   SCp->cmd_len, DMA_TO_DEVICE);				SCp->request_bufflen = sizeof(SCp->sense_buffer);				slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);				slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));				slot->SG[0].pAddr = bS_to_host(slot->dma_handle);				slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);				slot->SG[1].pAddr = 0;				slot->resume_offset = hostdata->pScript;				dma_cache_sync(slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE);				dma_cache_sync(SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);								/* queue the command for reissue */				slot->state = NCR_700_SLOT_QUEUED;				hostdata->state = NCR_700_HOST_FREE;				hostdata->cmd = NULL;			}		} else {			// Currently rely on the mid layer evaluation			// of the tag queuing capability			//			//if(status_byte(hostdata->status[0]) == GOOD &&			//   SCp->cmnd[0] == INQUIRY && SCp->use_sg == 0) {			//	/* Piggy back the tag queueing support			//	 * on this command */			//	dma_sync_single_for_cpu(hostdata->dev,			//			    slot->dma_handle,			//			    SCp->request_bufflen,			//			    DMA_FROM_DEVICE);			//	if(((char *)SCp->request_buffer)[7] & 0x02) {			//		printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);			//		hostdata->tag_negotiated |= (1<<SCp->device->id);			//		NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);			//	} else {			//		NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);			//		hostdata->tag_negotiated &= ~(1<<SCp->device->id);			//	}			//}			NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);		}	} else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {		__u8 i = (dsps & 0xf00) >> 8;		printk(KERN_ERR "scsi%d: (%d:%d), UNEXPECTED PHASE %s (%s)\n",		       host->host_no, pun, lun,		       NCR_700_phase[i],		       sbcl_to_string(NCR_700_readb(host, SBCL_REG)));		printk(KERN_ERR "         len = %d, cmd =", SCp->cmd_len);		scsi_print_command(SCp);		NCR_700_internal_bus_reset(host);	} else if((dsps & 0xfffff000) == A_FATAL) {		int i = (dsps & 0xfff);		printk(KERN_ERR "scsi%d: (%d:%d) FATAL ERROR: %s\n",		       host->host_no, pun, lun, NCR_700_fatal_messages[i]);		if(dsps == A_FATAL_ILLEGAL_MSG_LENGTH) {			printk(KERN_ERR "     msg begins %02x %02x\n",			       hostdata->msgin[0], hostdata->msgin[1]);		}		NCR_700_internal_bus_reset(host);	} else if((dsps & 0xfffff0f0) == A_DISCONNECT) {#ifdef NCR_700_DEBUG		__u8 i = (dsps & 0xf00) >> 8;		printk("scsi%d: (%d:%d), DISCONNECTED (%d) %s\n",		       host->host_no, pun, lun,		       i, NCR_700_phase[i]);#endif		save_for_reselection(hostdata, SCp, dsp);	} else if(dsps == A_RESELECTION_IDENTIFIED) {		__u8 lun;		struct NCR_700_command_slot *slot;		__u8 reselection_id = hostdata->reselection_id;		struct scsi_device *SDp;		lun = hostdata->msgin[0] & 0x1f;		hostdata->reselection_id = 0xff;		DEBUG(("scsi%d: (%d:%d) RESELECTED!\n",		       host->host_no, reselection_id, lun));		/* clear the reselection indicator */		SDp = __scsi_device_lookup(host, 0, reselection_id, lun);		if(unlikely(SDp == NULL)) {			printk(KERN_ERR "scsi%d: (%d:%d) HAS NO device\n",			       host->host_no, reselection_id, lun);			BUG();		}		if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {			struct scsi_cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);			if(unlikely(SCp == NULL)) {				printk(KERN_ERR "scsi%d: (%d:%d) no saved request for tag %d\n", 				       host->host_no, reselection_id, lun, hostdata->msgin[2]);				BUG();			}			slot = (struct NCR_700_command_slot *)SCp->host_scribble;			DEBUG(("53c700: %d:%d:%d, reselection is tag %d, slot %p(%d)\n",			       host->host_no, SDp->id, SDp->lun,			       hostdata->msgin[2], slot, slot->tag));		} else {			struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);			if(unlikely(SCp == NULL)) {				printk(KERN_ERR "scsi%d: (%d:%d) no saved request for untagged cmd\n", 				       host->host_no, reselection_id, lun);				BUG();			}			slot = (struct NCR_700_command_slot *)SCp->host_scribble;		}		if(slot == NULL) {			printk(KERN_ERR "scsi%d: (%d:%d) RESELECTED but no saved command (MSG = %02x %02x %02x)!!\n",			       host->host_no, reselection_id, lun,			       hostdata->msgin[0], hostdata->msgin[1],			       hostdata->msgin[2]);		} else {			if(hostdata->state != NCR_700_HOST_BUSY)				printk(KERN_ERR "scsi%d: FATAL, host not busy during valid reselection!\n",				       host->host_no);			resume_offset = slot->resume_offset;			hostdata->cmd = slot->cmnd;			/* re-patch for this command */			script_patch_32_abs(hostdata->script, CommandAddress, 					    slot->pCmd);			script_patch_16(hostdata->script,					CommandCount, slot->cmnd->cmd_len);			script_patch_32_abs(hostdata->script, SGScriptStartAddress,					    to32bit(&slot->pSG[0].ins));			/* Note: setting SXFER only works if we're			 * still in the MESSAGE phase, so it is vital			 * that ACK is still asserted when we process			 * the reselection message.  The resume offset			 * should therefore always clear ACK */			NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),				       host, SXFER_REG);			dma_cache_sync(hostdata->msgin,				       MSG_ARRAY_SIZE, DMA_FROM_DEVICE);			dma_cache_sync(hostdata->msgout,				       MSG_ARRAY_SIZE, DMA_TO_DEVICE);			/* I'm just being paranoid here, the command should			 * already have been flushed from the cache */			dma_cache_sync(slot->cmnd->cmnd,				       slot->cmnd->cmd_len, DMA_TO_DEVICE);					}	} else if(dsps == A_RESELECTED_DURING_SELECTION) {		/* This section is full of debugging code because I've		 * never managed to reach it.  I think what happens is		 * that, because the 700 runs with selection		 * interrupts enabled the whole time that we take a		 * selection interrupt before we manage to get to the		 * reselected script interrupt */		__u8 reselection_id = NCR_700_readb(host, SFBR_REG);		struct NCR_700_command_slot *slot;				/* Take out our own ID */		reselection_id &= ~(1<<host->this_id);				/* I've never seen this happen, so keep this as a printk rather		 * than a debug */		printk(KERN_INFO "scsi%d: (%d:%d) RESELECTION DURING SELECTION, dsp=%08x[%04x] state=%d, count=%d\n",		       host->host_no, reselection_id, lun, dsp, dsp - hostdata->pScript, hostdata->state, hostdata->command_slot_count);		{			/* FIXME: DEBUGGING CODE */			__u32 SG = (__u32)bS_to_cpu(hostdata->script[A_SGScriptStartAddress_used[0]]);			int i;			for(i=0; i< NCR_700_COMMAND_SLOTS_PER_HOST; i++) {				if(SG >= to32bit(&hostdata->slots[i].pSG[0])				   && SG <= to32bit(&hostdata->slots[i].pSG[NCR_700_SG_SEGMENTS]))					break;			}			printk(KERN_INFO "IDENTIFIED SG segment as being %08x in slot %p, cmd %p, slot->resume_offset=%08x\n", SG, &hostdata->slots[i], hostdata->slots[i].cmnd, hostdata->slots[i].resume_offset);			SCp =  hostdata->slots[i].cmnd;		}		if(SCp != NULL) {			slot = (struct NCR_700_command_slot *)SCp->host_scribble;			/* change slot from busy to queued to redo command */			slot->state = NCR_700_SLOT_QUEUED;		}		hostdata->cmd = NULL;				if(reselection_id == 0) {			if(hostdata->reselection_id == 0xff) {				printk(KERN_ERR "scsi%d: Invalid reselection during selection!!\n", host->host_no);				return 0;			} else {				printk(KERN_ERR "scsi%d: script reselected and we took a selection interrupt\n",				       host->host_no);				reselection_id = hostdata->reselection_id;			}		} else {						/* convert to real ID */			reselection_id = bitmap_to_number(reselection_id);		}		hostdata->reselection_id = reselection_id;		/* just in case we have a stale simple tag message, clear it */		hostdata->msgin[1] = 0;		dma_cache_sync(hostdata->msgin,			       MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL);		if(hostdata->tag_negotiated & (1<<reselection_id)) {			resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;		} else {			resume_offset = hostdata->pScript + Ent_GetReselectionData;		}	} else if(dsps == A_COMPLETED_SELECTION_AS_TARGET) {		/* we've just disconnected from the bus, do nothing since		 * a return here will re-run the queued command slot		 * that may have been interrupted by the initial selection */		DEBUG((" SELECTION COMPLETED\n"));	} else if((dsps & 0xfffff0f0) == A_MSG_IN) { 		resume_offset = process_message(host, hostdata, SCp,						dsp, dsps);	} else if((dsps &  0xfffff000) == 0) {		__u8 i = (dsps & 0xf0) >> 4, j = (dsps & 0xf00) >> 8;		printk(KERN_ERR "scsi%d: (%d:%d), unhandled script condition %s %s at %04x\n",		       host->host_no, pun, lun, NCR_700_condition[i],		       NCR_700_phase[j], dsp - hostdata->pScript);		if(SCp != NULL) {			scsi_print_command(SCp);			if(SCp->use_sg) {				for(i = 0; i < SCp->use_sg + 1; i++) {					printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);				}			}		}	       		NCR_700_internal_bus_reset(host);	} else if((dsps & 0xfffff000) == A_DEBUG_INTERRUPT) {		printk(KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %08x[%04x], continuing\n",		       host->host_no, pun, lun, dsps & 0xfff, dsp, dsp - hostdata->pScript);		resume_offset = dsp;	} else {		printk(KERN_ERR "scsi%d: (%d:%d), unidentified script interrupt 0x%x at %04x\n",		       host->host_no, pun, lun, dsps, dsp - hostdata->pScript);		NCR_700_internal_bus_reset(host);	}	return resume_offset;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/017560fca496f72ed9dd734ffde63ce39dfe0411/53c700.c/buggy/drivers/scsi/53c700.c