scsi_to_pci_dma_dir(SC-> sc_data_direction)); 
SC->sc_data_direction); 
ips_next(ips_ha_t * ha, int intr){	ips_scb_t *scb;	Scsi_Cmnd *SC;	Scsi_Cmnd *p;	Scsi_Cmnd *q;	ips_copp_wait_item_t *item;	int ret;	unsigned long cpu_flags = 0;	struct Scsi_Host *host;	METHOD_TRACE("ips_next", 1);	if (!ha)		return;	host = ips_sh[ha->host_num];	/*	 * Block access to the queue function so	 * this command won't time out	 */	if (intr == IPS_INTR_ON)		IPS_LOCK_SAVE(host->host_lock, cpu_flags);	if ((ha->subsys->param[3] & 0x300000)	    && (ha->scb_activelist.count == 0)) {		struct timeval tv;		do_gettimeofday(&tv);		if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {			ha->last_ffdc = tv.tv_sec;			ips_ffdc_time(ha);		}	}	/*	 * Send passthru commands	 * These have priority over normal I/O	 * but shouldn't affect performance too much	 * since we limit the number that can be active	 * on the card at any one time	 */	while ((ha->num_ioctl < IPS_MAX_IOCTL) &&	       (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) {		item = ips_removeq_copp_head(&ha->copp_waitlist);		ha->num_ioctl++;		if (intr == IPS_INTR_ON)			IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);		scb->scsi_cmd = item->scsi_cmd;		kfree(item);		ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);		if (intr == IPS_INTR_ON)			IPS_LOCK_SAVE(host->host_lock, cpu_flags);		switch (ret) {		case IPS_FAILURE:			if (scb->scsi_cmd) {				scb->scsi_cmd->result = DID_ERROR << 16;				scb->scsi_cmd->scsi_done(scb->scsi_cmd);			}			ips_freescb(ha, scb);			break;		case IPS_SUCCESS_IMM:			if (scb->scsi_cmd) {				scb->scsi_cmd->result = DID_OK << 16;				scb->scsi_cmd->scsi_done(scb->scsi_cmd);			}			ips_freescb(ha, scb);			break;		default:			break;		}		/* end case */		if (ret != IPS_SUCCESS) {			ha->num_ioctl--;			continue;		}		ret = ips_send_cmd(ha, scb);		if (ret == IPS_SUCCESS)			ips_putq_scb_head(&ha->scb_activelist, scb);		else			ha->num_ioctl--;		switch (ret) {		case IPS_FAILURE:			if (scb->scsi_cmd) {				scb->scsi_cmd->result = DID_ERROR << 16;			}			ips_freescb(ha, scb);			break;		case IPS_SUCCESS_IMM:			ips_freescb(ha, scb);			break;		default:			break;		}		/* end case */	}	/*	 * Send "Normal" I/O commands	 */	p = ha->scb_waitlist.head;	while ((p) && (scb = ips_getscb(ha))) {		if ((p->device->channel > 0)		    && (ha->			dcdb_active[p->device->channel -				    1] & (1 << p->device->id))) {			ips_freescb(ha, scb);			p = (Scsi_Cmnd *) p->host_scribble;			continue;		}		q = p;		SC = ips_removeq_wait(&ha->scb_waitlist, q);		if (intr == IPS_INTR_ON)			IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);	/* Unlock HA after command is taken off queue */		SC->result = DID_OK;		SC->host_scribble = NULL;		memset(SC->sense_buffer, 0, sizeof (SC->sense_buffer));		scb->target_id = SC->device->id;		scb->lun = SC->device->lun;		scb->bus = SC->device->channel;		scb->scsi_cmd = SC;		scb->breakup = 0;		scb->data_len = 0;		scb->callback = ipsintr_done;		scb->timeout = ips_cmd_timeout;		memset(&scb->cmd, 0, 16);		/* copy in the CDB */		memcpy(scb->cdb, SC->cmnd, SC->cmd_len);		/* Now handle the data buffer */		if (SC->use_sg) {			struct scatterlist *sg;			int i;			sg = SC->request_buffer;			scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg,						   scsi_to_pci_dma_dir(SC->								       sc_data_direction));			scb->flags |= IPS_SCB_MAP_SG;			for (i = 0; i < scb->sg_count; i++) {				if (ips_fill_scb_sg_single				    (ha, sg_dma_address(&sg[i]), scb, i,				     sg_dma_len(&sg[i])) < 0)					break;			}			scb->dcdb.transfer_length = scb->data_len;		} else {			if (SC->request_bufflen) {				scb->data_busaddr =				    pci_map_single(ha->pcidev,						   SC->request_buffer,						   SC->request_bufflen,						   scsi_to_pci_dma_dir(SC->								       sc_data_direction));				scb->flags |= IPS_SCB_MAP_SINGLE;				ips_fill_scb_sg_single(ha, scb->data_busaddr,						       scb, 0,						       SC->request_bufflen);				scb->dcdb.transfer_length = scb->data_len;			} else {				scb->data_busaddr = 0L;				scb->sg_len = 0;				scb->data_len = 0;				scb->dcdb.transfer_length = 0;			}		}		scb->dcdb.cmd_attribute =		    ips_command_direction[scb->scsi_cmd->cmnd[0]];        /* Allow a WRITE BUFFER Command to Have no Data */        /* This is Used by Tape Flash Utilites          */        if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) && (scb->data_len == 0))             scb->dcdb.cmd_attribute = 0;                  		if (!(scb->dcdb.cmd_attribute & 0x3))			scb->dcdb.transfer_length = 0;		if (scb->data_len >= IPS_MAX_XFER) {			scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;			scb->dcdb.transfer_length = 0;		}		if (intr == IPS_INTR_ON)			IPS_LOCK_SAVE(host->host_lock, cpu_flags);		ret = ips_send_cmd(ha, scb);		switch (ret) {		case IPS_SUCCESS:			ips_putq_scb_head(&ha->scb_activelist, scb);			break;		case IPS_FAILURE:			if (scb->scsi_cmd) {				scb->scsi_cmd->result = DID_ERROR << 16;				scb->scsi_cmd->scsi_done(scb->scsi_cmd);			}			if (scb->bus)				ha->dcdb_active[scb->bus - 1] &=				    ~(1 << scb->target_id);			ips_freescb(ha, scb);			break;		case IPS_SUCCESS_IMM:			if (scb->scsi_cmd)				scb->scsi_cmd->scsi_done(scb->scsi_cmd);			if (scb->bus)				ha->dcdb_active[scb->bus - 1] &=				    ~(1 << scb->target_id);			ips_freescb(ha, scb);			break;		default:			break;		}		/* end case */		p = (Scsi_Cmnd *) p->host_scribble;	}			/* end while */	if (intr == IPS_INTR_ON)		IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/be7db055dd7261522557046370f49160728e3847/ips.c/clean/drivers/scsi/ips.c