zfcp_unit_put(unit); 
zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,			       struct zfcp_unit *unit,			       struct scsi_cmnd * scsi_cmnd,			       struct timer_list *timer, int req_flags){	struct zfcp_fsf_req *fsf_req = NULL;	struct fcp_cmnd_iu *fcp_cmnd_iu;	unsigned int sbtype;	unsigned long lock_flags;	int real_bytes = 0;	int retval = 0;	int mask;	/* setup new FSF request */	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,				     adapter->pool.fsf_req_scsi,				     &lock_flags, &fsf_req);	if (unlikely(retval < 0)) {		ZFCP_LOG_DEBUG("error: Could not create FCP command request "			       "for unit 0x%016Lx on port 0x%016Lx on "			       "adapter %s\n",			       unit->fcp_lun,			       unit->port->wwpn,			       zfcp_get_busid_by_adapter(adapter));		goto failed_req_create;	}	/*	 * associate FSF request with SCSI request	 * (need this for look up on abort)	 */	fsf_req->data.send_fcp_command_task.fsf_req = fsf_req;	scsi_cmnd->host_scribble = (char *) &(fsf_req->data);	/*	 * associate SCSI command with FSF request	 * (need this for look up on normal command completion)	 */	fsf_req->data.send_fcp_command_task.scsi_cmnd = scsi_cmnd;	fsf_req->data.send_fcp_command_task.start_jiffies = jiffies;	fsf_req->data.send_fcp_command_task.unit = unit;	ZFCP_LOG_DEBUG("unit=%p, fcp_lun=0x%016Lx\n", unit, unit->fcp_lun);	/* set handles of unit and its parent port in QTCB */	fsf_req->qtcb->header.lun_handle = unit->handle;	fsf_req->qtcb->header.port_handle = unit->port->handle;	/* FSF does not define the structure of the FCP_CMND IU */	fcp_cmnd_iu = (struct fcp_cmnd_iu *)	    &(fsf_req->qtcb->bottom.io.fcp_cmnd);	/*	 * set depending on data direction:	 *      data direction bits in SBALE (SB Type)	 *      data direction bits in QTCB	 *      data direction bits in FCP_CMND IU	 */	switch (scsi_cmnd->sc_data_direction) {	case DMA_NONE:		fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;		/*		 * FIXME(qdio):		 * what is the correct type for commands		 * without 'real' data buffers?		 */		sbtype = SBAL_FLAGS0_TYPE_READ;		break;	case DMA_FROM_DEVICE:		fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ;		sbtype = SBAL_FLAGS0_TYPE_READ;		fcp_cmnd_iu->rddata = 1;		break;	case DMA_TO_DEVICE:		fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE;		sbtype = SBAL_FLAGS0_TYPE_WRITE;		fcp_cmnd_iu->wddata = 1;		break;	case DMA_BIDIRECTIONAL:	default:		/*		 * dummy, catch this condition earlier		 * in zfcp_scsi_queuecommand		 */		goto failed_scsi_cmnd;	}	/* set FC service class in QTCB (3 per default) */	fsf_req->qtcb->bottom.io.service_class = adapter->fc_service_class;	/* set FCP_LUN in FCP_CMND IU in QTCB */	fcp_cmnd_iu->fcp_lun = unit->fcp_lun;	mask = ZFCP_STATUS_UNIT_READONLY | ZFCP_STATUS_UNIT_SHARED;	/* set task attributes in FCP_CMND IU in QTCB */	if (likely((scsi_cmnd->device->simple_tags) ||		   (atomic_test_mask(mask, &unit->status))))		fcp_cmnd_iu->task_attribute = SIMPLE_Q;	else		fcp_cmnd_iu->task_attribute = UNTAGGED;	/* set additional length of FCP_CDB in FCP_CMND IU in QTCB, if needed */	if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH)) {		fcp_cmnd_iu->add_fcp_cdb_length		    = (scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2;		ZFCP_LOG_TRACE("SCSI CDB length is 0x%x, "			       "additional FCP_CDB length is 0x%x "			       "(shifted right 2 bits)\n",			       scsi_cmnd->cmd_len,			       fcp_cmnd_iu->add_fcp_cdb_length);	}	/*	 * copy SCSI CDB (including additional length, if any) to	 * FCP_CDB in FCP_CMND IU in QTCB	 */	memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);	/* FCP CMND IU length in QTCB */	fsf_req->qtcb->bottom.io.fcp_cmnd_length =		sizeof (struct fcp_cmnd_iu) +		fcp_cmnd_iu->add_fcp_cdb_length + sizeof (fcp_dl_t);	/* generate SBALEs from data buffer */	real_bytes = zfcp_qdio_sbals_from_scsicmnd(fsf_req, sbtype, scsi_cmnd);	if (unlikely(real_bytes < 0)) {		if (fsf_req->sbal_number < ZFCP_MAX_SBALS_PER_REQ) {			ZFCP_LOG_DEBUG(				"Data did not fit into available buffer(s), "			       "waiting for more...\n");		retval = -EIO;	} else {		ZFCP_LOG_NORMAL("error: No truncation implemented but "				"required. Shutting down unit "				"(adapter %s, port 0x%016Lx, "				"unit 0x%016Lx)\n",				zfcp_get_busid_by_unit(unit),				unit->port->wwpn,				unit->fcp_lun);		zfcp_erp_unit_shutdown(unit, 0);		retval = -EINVAL;		}		goto no_fit;	}	/* set length of FCP data length in FCP_CMND IU in QTCB */	zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes);	ZFCP_LOG_DEBUG("Sending SCSI command:\n");	ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,		      (char *) scsi_cmnd->cmnd, scsi_cmnd->cmd_len);	/*	 * start QDIO request for this FSF request	 *  covered by an SBALE)	 */	retval = zfcp_fsf_req_send(fsf_req, timer);	if (unlikely(retval < 0)) {		ZFCP_LOG_INFO("error: Could not send FCP command request "			      "on adapter %s, port 0x%016Lx, unit 0x%016Lx\n",			      zfcp_get_busid_by_adapter(adapter),			      unit->port->wwpn,			      unit->fcp_lun);		goto send_failed;	}	ZFCP_LOG_TRACE("Send FCP Command initiated (adapter %s, "		       "port 0x%016Lx, unit 0x%016Lx)\n",		       zfcp_get_busid_by_adapter(adapter),		       unit->port->wwpn,		       unit->fcp_lun);	goto success; send_failed: no_fit: failed_scsi_cmnd:	zfcp_fsf_req_free(fsf_req);	fsf_req = NULL;	scsi_cmnd->host_scribble = NULL; success: failed_req_create:	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);	return retval;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/059c97d0434834d291eff94669ca2dd3eaac9d28/zfcp_fsf.c/clean/drivers/s390/scsi/zfcp_fsf.c