printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->device->id, cmd->device->lun); 
scmd_printk(KERN_INFO, cmd, "switching to slow handshake\n"); 
static void NCR5380_information_transfer(struct Scsi_Host *instance) {	NCR5380_local_declare();	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)instance->hostdata;	unsigned char msgout = NOP;	int sink = 0;	int len;#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)	int transfersize;#endif	unsigned char *data;	unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;	Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;	/* RvC: we need to set the end of the polling time */	unsigned long poll_time = jiffies + USLEEP_POLL;	NCR5380_setup(instance);	while (1) {		tmp = NCR5380_read(STATUS_REG);		/* We only have a valid SCSI phase when REQ is asserted */		if (tmp & SR_REQ) {			phase = (tmp & PHASE_MASK);			if (phase != old_phase) {				old_phase = phase;				NCR5380_dprint_phase(NDEBUG_INFORMATION, instance);			}			if (sink && (phase != PHASE_MSGOUT)) {				NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);				while (NCR5380_read(STATUS_REG) & SR_REQ);				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);				sink = 0;				continue;			}			switch (phase) {			case PHASE_DATAIN:			case PHASE_DATAOUT:#if (NDEBUG & NDEBUG_NO_DATAOUT)				printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n", instance->host_no);				sink = 1;				do_abort(instance);				cmd->result = DID_ERROR << 16;				cmd->done(cmd);				return;#endif				/* 				 * If there is no room left in the current buffer in the				 * scatter-gather list, move onto the next one.				 */				if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {					++cmd->SCp.buffer;					--cmd->SCp.buffers_residual;					cmd->SCp.this_residual = cmd->SCp.buffer->length;					cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+						       cmd->SCp.buffer->offset;					dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));				}				/*				 * The preferred transfer method is going to be 				 * PSEUDO-DMA for systems that are strictly PIO,				 * since we can let the hardware do the handshaking.				 *				 * For this to work, we need to know the transfersize				 * ahead of time, since the pseudo-DMA code will sit				 * in an unconditional loop.				 */#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)				/* KLL				 * PSEUDO_DMA is defined here. If this is the g_NCR5380				 * driver then it will always be defined, so the				 * FLAG_NO_PSEUDO_DMA is used to inhibit PDMA in the base				 * NCR5380 case.  I think this is a fairly clean solution.				 * We supplement these 2 if's with the flag.				 */#ifdef NCR5380_dma_xfer_len				if (!cmd->device->borken && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {#else				transfersize = cmd->transfersize;#ifdef LIMIT_TRANSFERSIZE	/* If we have problems with interrupt service */				if (transfersize > 512)					transfersize = 512;#endif				/* LIMIT_TRANSFERSIZE */				if (!cmd->device->borken && transfersize && !(hostdata->flags & FLAG_NO_PSEUDO_DMA) && cmd->SCp.this_residual && !(cmd->SCp.this_residual % transfersize)) {					/* Limit transfers to 32K, for xx400 & xx406					 * pseudoDMA that transfers in 128 bytes blocks. */					if (transfersize > 32 * 1024)						transfersize = 32 * 1024;#endif					len = transfersize;					if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) {						/*						 * If the watchdog timer fires, all future accesses to this						 * device will use the polled-IO.						 */						printk("scsi%d : switching target %d lun %d to slow handshake\n", instance->host_no, cmd->device->id, cmd->device->lun);						cmd->device->borken = 1;						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);						sink = 1;						do_abort(instance);						cmd->result = DID_ERROR << 16;						cmd->done(cmd);						/* XXX - need to source or sink data here, as appropriate */					} else						cmd->SCp.this_residual -= transfersize - len;				} else#endif				/* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */					NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **)							     &cmd->SCp.ptr);				break;			case PHASE_MSGIN:				len = 1;				data = &tmp;				NCR5380_transfer_pio(instance, &phase, &len, &data);				cmd->SCp.Message = tmp;				switch (tmp) {					/*					 * Linking lets us reduce the time required to get the 					 * next command out to the device, hopefully this will					 * mean we don't waste another revolution due to the delays					 * required by ARBITRATION and another SELECTION.					 *					 * In the current implementation proposal, low level drivers					 * merely have to start the next command, pointed to by 					 * next_link, done() is called as with unlinked commands.					 */#ifdef LINKED				case LINKED_CMD_COMPLETE:				case LINKED_FLG_CMD_COMPLETE:					/* Accept message by clearing ACK */					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);					dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked command complete.\n", instance->host_no, cmd->device->id, cmd->device->lun));					/* 					 * Sanity check : A linked command should only terminate with					 * one of these messages if there are more linked commands					 * available.					 */					if (!cmd->next_link) {						printk("scsi%d : target %d lun %d linked command complete, no next_link\n" instance->host_no, cmd->device->id, cmd->device->lun);						sink = 1;						do_abort(instance);						return;					}					initialize_SCp(cmd->next_link);					/* The next command is still part of this process */					cmd->next_link->tag = cmd->tag;					cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);					dprintk(NDEBUG_LINKED, ("scsi%d : target %d lun %d linked request done, calling scsi_done().\n", instance->host_no, cmd->device->id, cmd->device->lun));					collect_stats(hostdata, cmd);					cmd->scsi_done(cmd);					cmd = hostdata->connected;					break;#endif				/* def LINKED */				case ABORT:				case COMMAND_COMPLETE:					/* Accept message by clearing ACK */					sink = 1;					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);					hostdata->connected = NULL;					dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d, lun %d completed\n", instance->host_no, cmd->device->id, cmd->device->lun));					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);					/* 					 * I'm not sure what the correct thing to do here is : 					 * 					 * If the command that just executed is NOT a request 					 * sense, the obvious thing to do is to set the result					 * code to the values of the stored parameters.					 * 					 * If it was a REQUEST SENSE command, we need some way 					 * to differentiate between the failure code of the original					 * and the failure code of the REQUEST sense - the obvious					 * case is success, where we fall through and leave the result					 * code unchanged.					 * 					 * The non-obvious place is where the REQUEST SENSE failed 					 */					if (cmd->cmnd[0] != REQUEST_SENSE)						cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);					else if (status_byte(cmd->SCp.Status) != GOOD)						cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);#ifdef AUTOSENSE					if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {						dprintk(NDEBUG_AUTOSENSE, ("scsi%d : performing request sense\n", instance->host_no));						cmd->cmnd[0] = REQUEST_SENSE;						cmd->cmnd[1] &= 0xe0;						cmd->cmnd[2] = 0;						cmd->cmnd[3] = 0;						cmd->cmnd[4] = sizeof(cmd->sense_buffer);						cmd->cmnd[5] = 0;						cmd->SCp.buffer = NULL;						cmd->SCp.buffers_residual = 0;						cmd->SCp.ptr = (char *) cmd->sense_buffer;						cmd->SCp.this_residual = sizeof(cmd->sense_buffer);						LIST(cmd, hostdata->issue_queue);						cmd->host_scribble = (unsigned char *)						    hostdata->issue_queue;						hostdata->issue_queue = (Scsi_Cmnd *) cmd;						dprintk(NDEBUG_QUEUES, ("scsi%d : REQUEST SENSE added to head of issue queue\n", instance->host_no));					} else#endif				/* def AUTOSENSE */					{						collect_stats(hostdata, cmd);						cmd->scsi_done(cmd);					}					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);					/* 					 * Restore phase bits to 0 so an interrupted selection, 					 * arbitration can resume.					 */					NCR5380_write(TARGET_COMMAND_REG, 0);					while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)						barrier();					return;				case MESSAGE_REJECT:					/* Accept message by clearing ACK */					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);					switch (hostdata->last_message) {					case HEAD_OF_QUEUE_TAG:					case ORDERED_QUEUE_TAG:					case SIMPLE_QUEUE_TAG:						cmd->device->simple_tags = 0;						hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);						break;					default:						break;					}				case DISCONNECT:{						/* Accept message by clearing ACK */						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);						cmd->device->disconnect = 1;						LIST(cmd, hostdata->disconnected_queue);						cmd->host_scribble = (unsigned char *)						    hostdata->disconnected_queue;						hostdata->connected = NULL;						hostdata->disconnected_queue = cmd;						dprintk(NDEBUG_QUEUES, ("scsi%d : command for target %d lun %d was moved from connected to" "  the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun));						/* 						 * Restore phase bits to 0 so an interrupted selection, 						 * arbitration can resume.						 */						NCR5380_write(TARGET_COMMAND_REG, 0);						/* Enable reselect interrupts */						NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);						/* Wait for bus free to avoid nasty timeouts - FIXME timeout !*/						/* NCR538_poll_politely(instance, STATUS_REG, SR_BSY, 0, 30 * HZ); */						while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)							barrier();						return;					}					/* 					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect					 * operation, in violation of the SCSI spec so we can safely 					 * ignore SAVE/RESTORE pointers calls.					 *					 * Unfortunately, some disks violate the SCSI spec and 					 * don't issue the required SAVE_POINTERS message before					 * disconnecting, and we have to break spec to remain 					 * compatible.					 */				case SAVE_POINTERS:				case RESTORE_POINTERS:					/* Accept message by clearing ACK */					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);					break;				case EXTENDED_MESSAGE:/*  * Extended messages are sent in the following format : * Byte          * 0            EXTENDED_MESSAGE == 1 * 1            length (includes one byte for code, doesn't  *              include first two bytes) * 2            code * 3..length+1  arguments * * Start the extended message buffer with the EXTENDED_MESSAGE * byte, since scsi_print_msg() wants the whole thing.   */					extended_msg[0] = EXTENDED_MESSAGE;					/* Accept first byte by clearing ACK */					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);					dprintk(NDEBUG_EXTENDED, ("scsi%d : receiving extended message\n", instance->host_no));					len = 2;					data = extended_msg + 1;					phase = PHASE_MSGIN;					NCR5380_transfer_pio(instance, &phase, &len, &data);					dprintk(NDEBUG_EXTENDED, ("scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]));					if (!len && extended_msg[1] <= (sizeof(extended_msg) - 1)) {						/* Accept third byte by clearing ACK */						NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);						len = extended_msg[1] - 1;						data = extended_msg + 3;						phase = PHASE_MSGIN;						NCR5380_transfer_pio(instance, &phase, &len, &data);						dprintk(NDEBUG_EXTENDED, ("scsi%d : message received, residual %d\n", instance->host_no, len));						switch (extended_msg[2]) {						case EXTENDED_SDTR:						case EXTENDED_WDTR:						case EXTENDED_MODIFY_DATA_POINTER:						case EXTENDED_EXTENDED_IDENTIFY:							tmp = 0;						}					} else if (len) {						printk("scsi%d: error receiving extended message\n", instance->host_no);						tmp = 0;					} else {						printk("scsi%d: extended message code %02x length %d is too long\n", instance->host_no, extended_msg[2], extended_msg[1]);						tmp = 0;					}					/* Fall through to reject message */					/* 					 * If we get something weird that we aren't expecting, 					 * reject it.					 */				default:					if (!tmp) {						printk("scsi%d: rejecting message ", instance->host_no);						scsi_print_msg(extended_msg);						printk("\n");					} else if (tmp != EXTENDED_MESSAGE)						printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n", instance->host_no, tmp, cmd->device->id, cmd->device->lun);					else						printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n", instance->host_no, extended_msg[1], extended_msg[0], cmd->device->id, cmd->device->lun);					msgout = MESSAGE_REJECT;					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);					break;				}	/* switch (tmp) */				break;			case PHASE_MSGOUT:				len = 1;				data = &msgout;				hostdata->last_message = msgout;				NCR5380_transfer_pio(instance, &phase, &len, &data);				if (msgout == ABORT) {					hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);					hostdata->connected = NULL;					cmd->result = DID_ERROR << 16;					collect_stats(hostdata, cmd);					cmd->scsi_done(cmd);					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);					return;				}				msgout = NOP;				break;			case PHASE_CMDOUT:				len = cmd->cmd_len;				data = cmd->cmnd;				/* 				 * XXX for performance reasons, on machines with a 				 * PSEUDO-DMA architecture we should probably 				 * use the dma transfer function.  				 */				NCR5380_transfer_pio(instance, &phase, &len, &data);				if (!cmd->device->disconnect && should_disconnect(cmd->cmnd[0])) {					NCR5380_set_timer(hostdata, USLEEP_SLEEP);					dprintk(NDEBUG_USLEEP, ("scsi%d : issued command, sleeping until %ul\n", instance->host_no, hostdata->time_expires));					return;				}				break;			case PHASE_STATIN:				len = 1;				data = &tmp;				NCR5380_transfer_pio(instance, &phase, &len, &data);				cmd->SCp.Status = tmp;				break;			default:				printk("scsi%d : unknown phase\n", instance->host_no);				NCR5380_dprint(NDEBUG_ALL, instance);			}	/* switch(phase) */		}		/* if (tmp * SR_REQ) */		else {			/* RvC: go to sleep if polling time expired			 */			if (!cmd->device->disconnect && time_after_eq(jiffies, poll_time)) {				NCR5380_set_timer(hostdata, USLEEP_SLEEP);				dprintk(NDEBUG_USLEEP, ("scsi%d : poll timed out, sleeping until %ul\n", instance->host_no, hostdata->time_expires));				return;			}		}	}			/* while (1) */}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/017560fca496f72ed9dd734ffde63ce39dfe0411/NCR5380.c/buggy/drivers/scsi/NCR5380.c