printf("%s:%d:%d:%d: Attempting to queue a%s message\n", ahc_name(ahc), cmd->device->channel, cmd->device->id, cmd->device->lun, 
scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n", 
ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag){	struct ahc_softc *ahc;	struct ahc_linux_device *dev;	struct scb *pending_scb;	u_int  saved_scbptr;	u_int  active_scb_index;	u_int  last_phase;	u_int  saved_scsiid;	u_int  cdb_byte;	int    retval;	int    was_paused;	int    paused;	int    wait;	int    disconnected;	pending_scb = NULL;	paused = FALSE;	wait = FALSE;	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;	printf("%s:%d:%d:%d: Attempting to queue a%s message\n",	       ahc_name(ahc), cmd->device->channel,	       cmd->device->id, cmd->device->lun,	       flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");	printf("CDB:");	for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)		printf(" 0x%x", cmd->cmnd[cdb_byte]);	printf("\n");	spin_lock_irq(&ahc->platform_data->spin_lock);	/*	 * First determine if we currently own this command.	 * Start by searching the device queue.  If not found	 * there, check the pending_scb list.  If not found	 * at all, and the system wanted us to just abort the	 * command, return success.	 */	dev = scsi_transport_device_data(cmd->device);	if (dev == NULL) {		/*		 * No target device for this command exists,		 * so we must not still own the command.		 */		printf("%s:%d:%d:%d: Is not an active device\n",		       ahc_name(ahc), cmd->device->channel, cmd->device->id,		       cmd->device->lun);		retval = SUCCESS;		goto no_cmd;	}	if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0	 && ahc_search_untagged_queues(ahc, cmd, cmd->device->id,				       cmd->device->channel + 'A',				       cmd->device->lun,				       CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) {		printf("%s:%d:%d:%d: Command found on untagged queue\n",		       ahc_name(ahc), cmd->device->channel, cmd->device->id,		       cmd->device->lun);		retval = SUCCESS;		goto done;	}	/*	 * See if we can find a matching cmd in the pending list.	 */	LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {		if (pending_scb->io_ctx == cmd)			break;	}	if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {		/* Any SCB for this device will do for a target reset */		LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {		  	if (ahc_match_scb(ahc, pending_scb, cmd->device->id,					  cmd->device->channel + 'A',					  CAM_LUN_WILDCARD,					  SCB_LIST_NULL, ROLE_INITIATOR) == 0)				break;		}	}	if (pending_scb == NULL) {		printf("%s:%d:%d:%d: Command not found\n",		       ahc_name(ahc), cmd->device->channel, cmd->device->id,		       cmd->device->lun);		goto no_cmd;	}	if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {		/*		 * We can't queue two recovery actions using the same SCB		 */		retval = FAILED;		goto  done;	}	/*	 * Ensure that the card doesn't do anything	 * behind our back and that we didn't "just" miss	 * an interrupt that would affect this cmd.	 */	was_paused = ahc_is_paused(ahc);	ahc_pause_and_flushwork(ahc);	paused = TRUE;	if ((pending_scb->flags & SCB_ACTIVE) == 0) {		printf("%s:%d:%d:%d: Command already completed\n",		       ahc_name(ahc), cmd->device->channel, cmd->device->id,		       cmd->device->lun);		goto no_cmd;	}	printf("%s: At time of recovery, card was %spaused\n",	       ahc_name(ahc), was_paused ? "" : "not ");	ahc_dump_card_state(ahc);	disconnected = TRUE;	if (flag == SCB_ABORT) {		if (ahc_search_qinfifo(ahc, cmd->device->id,				       cmd->device->channel + 'A',				       cmd->device->lun,				       pending_scb->hscb->tag,				       ROLE_INITIATOR, CAM_REQ_ABORTED,				       SEARCH_COMPLETE) > 0) {			printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",			       ahc_name(ahc), cmd->device->channel,					cmd->device->id, cmd->device->lun);			retval = SUCCESS;			goto done;		}	} else if (ahc_search_qinfifo(ahc, cmd->device->id,				      cmd->device->channel + 'A',				      cmd->device->lun, pending_scb->hscb->tag,				      ROLE_INITIATOR, /*status*/0,				      SEARCH_COUNT) > 0) {		disconnected = FALSE;	}	if (disconnected && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {		struct scb *bus_scb;		bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG));		if (bus_scb == pending_scb)			disconnected = FALSE;		else if (flag != SCB_ABORT		      && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid		      && ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb))			disconnected = FALSE;	}	/*	 * At this point, pending_scb is the scb associated with the	 * passed in command.  That command is currently active on the	 * bus, is in the disconnected state, or we're hoping to find	 * a command for the same target active on the bus to abuse to	 * send a BDR.  Queue the appropriate message based on which of	 * these states we are in.	 */	last_phase = ahc_inb(ahc, LASTPHASE);	saved_scbptr = ahc_inb(ahc, SCBPTR);	active_scb_index = ahc_inb(ahc, SCB_TAG);	saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);	if (last_phase != P_BUSFREE	 && (pending_scb->hscb->tag == active_scb_index	  || (flag == SCB_DEVICE_RESET	   && SCSIID_TARGET(ahc, saved_scsiid) == cmd->device->id))) {		/*		 * We're active on the bus, so assert ATN		 * and hope that the target responds.		 */		pending_scb = ahc_lookup_scb(ahc, active_scb_index);		pending_scb->flags |= SCB_RECOVERY_SCB|flag;		ahc_outb(ahc, MSG_OUT, HOST_MSG);		ahc_outb(ahc, SCSISIGO, last_phase|ATNO);		printf("%s:%d:%d:%d: Device is active, asserting ATN\n",		       ahc_name(ahc), cmd->device->channel, cmd->device->id,		       cmd->device->lun);		wait = TRUE;	} else if (disconnected) {		/*		 * Actually re-queue this SCB in an attempt		 * to select the device before it reconnects.		 * In either case (selection or reselection),		 * we will now issue the approprate message		 * to the timed-out device.		 *		 * Set the MK_MESSAGE control bit indicating		 * that we desire to send a message.  We		 * also set the disconnected flag since		 * in the paging case there is no guarantee		 * that our SCB control byte matches the		 * version on the card.  We don't want the		 * sequencer to abort the command thinking		 * an unsolicited reselection occurred.		 */		pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;		pending_scb->flags |= SCB_RECOVERY_SCB|flag;		/*		 * Remove any cached copy of this SCB in the		 * disconnected list in preparation for the		 * queuing of our abort SCB.  We use the		 * same element in the SCB, SCB_NEXT, for		 * both the qinfifo and the disconnected list.		 */		ahc_search_disc_list(ahc, cmd->device->id,				     cmd->device->channel + 'A',				     cmd->device->lun, pending_scb->hscb->tag,				     /*stop_on_first*/TRUE,				     /*remove*/TRUE,				     /*save_state*/FALSE);		/*		 * In the non-paging case, the sequencer will		 * never re-reference the in-core SCB.		 * To make sure we are notified during		 * reslection, set the MK_MESSAGE flag in		 * the card's copy of the SCB.		 */		if ((ahc->flags & AHC_PAGESCBS) == 0) {			ahc_outb(ahc, SCBPTR, pending_scb->hscb->tag);			ahc_outb(ahc, SCB_CONTROL,				 ahc_inb(ahc, SCB_CONTROL)|MK_MESSAGE);		}		/*		 * Clear out any entries in the QINFIFO first		 * so we are the next SCB for this target		 * to run.		 */		ahc_search_qinfifo(ahc, cmd->device->id,				   cmd->device->channel + 'A',				   cmd->device->lun, SCB_LIST_NULL,				   ROLE_INITIATOR, CAM_REQUEUE_REQ,				   SEARCH_COMPLETE);		ahc_qinfifo_requeue_tail(ahc, pending_scb);		ahc_outb(ahc, SCBPTR, saved_scbptr);		ahc_print_path(ahc, pending_scb);		printf("Device is disconnected, re-queuing SCB\n");		wait = TRUE;	} else {		printf("%s:%d:%d:%d: Unable to deliver message\n",		       ahc_name(ahc), cmd->device->channel, cmd->device->id,		       cmd->device->lun);		retval = FAILED;		goto done;	}no_cmd:	/*	 * Our assumption is that if we don't have the command, no	 * recovery action was required, so we return success.  Again,	 * the semantics of the mid-layer recovery engine are not	 * well defined, so this may change in time.	 */	retval = SUCCESS;done:	if (paused)		ahc_unpause(ahc);	if (wait) {		struct timer_list timer;		int ret;		ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE;		spin_unlock_irq(&ahc->platform_data->spin_lock);		init_timer(&timer);		timer.data = (u_long)ahc;		timer.expires = jiffies + (5 * HZ);		timer.function = ahc_linux_sem_timeout;		add_timer(&timer);		printf("Recovery code sleeping\n");		down(&ahc->platform_data->eh_sem);		printf("Recovery code awake\n");        	ret = del_timer_sync(&timer);		if (ret == 0) {			printf("Timer Expired\n");			retval = FAILED;		}		spin_lock_irq(&ahc->platform_data->spin_lock);	}	spin_unlock_irq(&ahc->platform_data->spin_lock);	return (retval);}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/017560fca496f72ed9dd734ffde63ce39dfe0411/aic7xxx_osm.c/clean/drivers/scsi/aic7xxx/aic7xxx_osm.c