}  TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) { if (list_acmd == acmd) break; }  if (list_acmd != NULL) { printf("%s:%d:%d:%d: Command found on device queue\n", ahd_name(ahd), cmd->device->channel, cmd->device->id, cmd->device->lun); TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); cmd->result = DID_ABORT << 16; ahd_linux_queue_cmd_complete(ahd, cmd); retval = SUCCESS; goto done; 
ahd_linux_abort(Scsi_Cmnd *cmd){	struct ahd_softc *ahd;	struct ahd_cmd *acmd;	struct ahd_cmd *list_acmd;	struct ahd_linux_device *dev;	struct scb *pending_scb;	u_long s;	u_int  saved_scbptr;	u_int  active_scbptr;	u_int  last_phase;	u_int  cdb_byte;	int    retval;	int    was_paused;	int    paused;	int    wait;	int    disconnected;	ahd_mode_state saved_modes;	pending_scb = NULL;	paused = FALSE;	wait = FALSE;	ahd = *(struct ahd_softc **)cmd->device->host->hostdata;	acmd = (struct ahd_cmd *)cmd;	printf("%s:%d:%d:%d: Attempting to abort cmd %p:",	       ahd_name(ahd), cmd->device->channel, cmd->device->id,	       cmd->device->lun, cmd);	for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)		printf(" 0x%x", cmd->cmnd[cdb_byte]);	printf("\n");	/*	 * In all versions of Linux, we have to work around	 * a major flaw in how the mid-layer is locked down	 * if we are to sleep successfully in our error handler	 * while allowing our interrupt handler to run.  Since	 * the midlayer acquires either the io_request_lock or	 * our lock prior to calling us, we must use the	 * spin_unlock_irq() method for unlocking our lock.	 * This will force interrupts to be enabled on the	 * current CPU.  Since the EH thread should not have	 * been running with CPU interrupts disabled other than	 * by acquiring either the io_request_lock or our own	 * lock, this *should* be safe.	 */	ahd_midlayer_entrypoint_lock(ahd, &s);	/*	 * 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 = ahd_linux_get_device(ahd, cmd->device->channel,				   cmd->device->id, cmd->device->lun,				   /*alloc*/FALSE);	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",		       ahd_name(ahd), cmd->device->channel, cmd->device->id,		       cmd->device->lun);		retval = SUCCESS;		goto no_cmd;	}	TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) {		if (list_acmd == acmd)			break;	}	if (list_acmd != NULL) {		printf("%s:%d:%d:%d: Command found on device queue\n",		       ahd_name(ahd), cmd->device->channel, cmd->device->id,		       cmd->device->lun);		TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe);		cmd->result = DID_ABORT << 16;		ahd_linux_queue_cmd_complete(ahd, cmd);		retval = SUCCESS;		goto done;	}	/*	 * See if we can find a matching cmd in the pending list.	 */	LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {		if (pending_scb->io_ctx == cmd)			break;	}	if (pending_scb == NULL) {		printf("%s:%d:%d:%d: Command not found\n",		       ahd_name(ahd), 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.  Also make sure that we	 * didn't "just" miss an interrupt that would	 * affect this cmd.	 */	was_paused = ahd_is_paused(ahd);	ahd_pause_and_flushwork(ahd);	paused = TRUE;	if ((pending_scb->flags & SCB_ACTIVE) == 0) {		printf("%s:%d:%d:%d: Command already completed\n",		       ahd_name(ahd), cmd->device->channel, cmd->device->id,		       cmd->device->lun);		goto no_cmd;	}	printf("%s: At time of recovery, card was %spaused\n",	       ahd_name(ahd), was_paused ? "" : "not ");	ahd_dump_card_state(ahd);	disconnected = TRUE;	if (ahd_search_qinfifo(ahd, cmd->device->id, cmd->device->channel + 'A',			       cmd->device->lun, SCB_GET_TAG(pending_scb),			       ROLE_INITIATOR, CAM_REQ_ABORTED,			       SEARCH_COMPLETE) > 0) {		printf("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",		       ahd_name(ahd), cmd->device->channel, cmd->device->id,				cmd->device->lun);		retval = SUCCESS;		goto done;	}	saved_modes = ahd_save_modes(ahd);	ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);	last_phase = ahd_inb(ahd, LASTPHASE);	saved_scbptr = ahd_get_scbptr(ahd);	active_scbptr = saved_scbptr;	if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {		struct scb *bus_scb;		bus_scb = ahd_lookup_scb(ahd, active_scbptr);		if (bus_scb == 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 or is in the disconnected state.	 */	if (last_phase != P_BUSFREE	 && SCB_GET_TAG(pending_scb) == active_scbptr) {		/*		 * We're active on the bus, so assert ATN		 * and hope that the target responds.		 */		pending_scb = ahd_lookup_scb(ahd, active_scbptr);		pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;		ahd_outb(ahd, MSG_OUT, HOST_MSG);		ahd_outb(ahd, SCSISIGO, last_phase|ATNO);		printf("%s:%d:%d:%d: Device is active, asserting ATN\n",		       ahd_name(ahd), 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.		 */		pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;		ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));		pending_scb->hscb->cdb_len = 0;		pending_scb->hscb->task_attribute = 0;		pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK;		if ((pending_scb->flags & SCB_PACKETIZED) != 0) {			/*			 * Mark the SCB has having an outstanding			 * task management function.  Should the command			 * complete normally before the task management			 * function can be sent, the host will be notified			 * to abort our requeued SCB.			 */			ahd_outb(ahd, SCB_TASK_MANAGEMENT,				 pending_scb->hscb->task_management);		} else {			/*			 * If non-packetized, set the MK_MESSAGE control			 * bit indicating that we desire to send a message.			 * We also set the disconnected flag since 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;			/*			 * 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.			 */			ahd_outb(ahd, SCB_CONTROL,				 ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);		}		/*		 * Clear out any entries in the QINFIFO first		 * so we are the next SCB for this target		 * to run.		 */		ahd_search_qinfifo(ahd, cmd->device->id,				   cmd->device->channel + 'A', cmd->device->lun,				   SCB_LIST_NULL, ROLE_INITIATOR,				   CAM_REQUEUE_REQ, SEARCH_COMPLETE);		ahd_qinfifo_requeue_tail(ahd, pending_scb);		ahd_set_scbptr(ahd, saved_scbptr);		ahd_print_path(ahd, pending_scb);		printf("Device is disconnected, re-queuing SCB\n");		wait = TRUE;	} else {		printf("%s:%d:%d:%d: Unable to deliver message\n",		       ahd_name(ahd), 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)		ahd_unpause(ahd);	if (wait) {		struct timer_list timer;		int ret;		pending_scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;		spin_unlock_irq(&ahd->platform_data->spin_lock);		init_timer(&timer);		timer.data = (u_long)pending_scb;		timer.expires = jiffies + (5 * HZ);		timer.function = ahd_linux_sem_timeout;		add_timer(&timer);		printf("Recovery code sleeping\n");		down(&ahd->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(&ahd->platform_data->spin_lock);	}	ahd_schedule_runq(ahd);	ahd_linux_run_complete_queue(ahd);	ahd_midlayer_entrypoint_unlock(ahd, &s);	return (retval);}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/60a13213840296b1e32d6781653a0eaa83d04382/aic79xx_osm.c/buggy/drivers/scsi/aic7xxx/aic79xx_osm.c