brintos

brintos / linux-shallow public Read only

0
0
Text · 106.4 KiB · 16d085d Raw
4072 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*******************************************************************************3 * IBM Virtual SCSI Target Driver4 * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp.5 *			   Santiago Leon (santil@us.ibm.com) IBM Corp.6 *			   Linda Xie (lxie@us.ibm.com) IBM Corp.7 *8 * Copyright (C) 2005-2011 FUJITA Tomonori <tomof@acm.org>9 * Copyright (C) 2010 Nicholas A. Bellinger <nab@kernel.org>10 *11 * Authors: Bryant G. Ly <bryantly@linux.vnet.ibm.com>12 * Authors: Michael Cyr <mikecyr@linux.vnet.ibm.com>13 *14 ****************************************************************************/15 16#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt17 18#include <linux/module.h>19#include <linux/kernel.h>20#include <linux/slab.h>21#include <linux/types.h>22#include <linux/list.h>23#include <linux/string.h>24#include <linux/delay.h>25#include <linux/of.h>26 27#include <target/target_core_base.h>28#include <target/target_core_fabric.h>29 30#include <asm/hvcall.h>31#include <asm/vio.h>32 33#include <scsi/viosrp.h>34 35#include "ibmvscsi_tgt.h"36 37#define IBMVSCSIS_VERSION	"v0.2"38 39#define	INITIAL_SRP_LIMIT	102440#define	DEFAULT_MAX_SECTORS	25641#define MAX_TXU			1024 * 102442 43static uint max_vdma_size = MAX_H_COPY_RDMA;44 45static char system_id[SYS_ID_NAME_LEN] = "";46static char partition_name[PARTITION_NAMELEN] = "UNKNOWN";47static uint partition_number = -1;48 49/* Adapter list and lock to control it */50static DEFINE_SPINLOCK(ibmvscsis_dev_lock);51static LIST_HEAD(ibmvscsis_dev_list);52 53static long ibmvscsis_parse_command(struct scsi_info *vscsi,54				    struct viosrp_crq *crq);55 56static void ibmvscsis_adapter_idle(struct scsi_info *vscsi);57 58static void ibmvscsis_determine_resid(struct se_cmd *se_cmd,59				      struct srp_rsp *rsp)60{61	u32 residual_count = se_cmd->residual_count;62 63	if (!residual_count)64		return;65 66	if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {67		if (se_cmd->data_direction == DMA_TO_DEVICE) {68			/* residual data from an underflow write */69			rsp->flags = SRP_RSP_FLAG_DOUNDER;70			rsp->data_out_res_cnt = cpu_to_be32(residual_count);71		} else if (se_cmd->data_direction == DMA_FROM_DEVICE) {72			/* residual data from an underflow read */73			rsp->flags = SRP_RSP_FLAG_DIUNDER;74			rsp->data_in_res_cnt = cpu_to_be32(residual_count);75		}76	} else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {77		if (se_cmd->data_direction == DMA_TO_DEVICE) {78			/* residual data from an overflow write */79			rsp->flags = SRP_RSP_FLAG_DOOVER;80			rsp->data_out_res_cnt = cpu_to_be32(residual_count);81		} else if (se_cmd->data_direction == DMA_FROM_DEVICE) {82			/* residual data from an overflow read */83			rsp->flags = SRP_RSP_FLAG_DIOVER;84			rsp->data_in_res_cnt = cpu_to_be32(residual_count);85		}86	}87}88 89/**90 * connection_broken() - Determine if the connection to the client is good91 * @vscsi:	Pointer to our adapter structure92 *93 * This function attempts to send a ping MAD to the client. If the call to94 * queue the request returns H_CLOSED then the connection has been broken95 * and the function returns TRUE.96 *97 * EXECUTION ENVIRONMENT:98 *	Interrupt or Process environment99 */100static bool connection_broken(struct scsi_info *vscsi)101{102	struct viosrp_crq *crq;103	u64 buffer[2] = { 0, 0 };104	long h_return_code;105	bool rc = false;106 107	/* create a PING crq */108	crq = (struct viosrp_crq *)&buffer;109	crq->valid = VALID_CMD_RESP_EL;110	crq->format = MESSAGE_IN_CRQ;111	crq->status = PING;112 113	h_return_code = h_send_crq(vscsi->dds.unit_id,114				   cpu_to_be64(buffer[MSG_HI]),115				   cpu_to_be64(buffer[MSG_LOW]));116 117	dev_dbg(&vscsi->dev, "Connection_broken: rc %ld\n", h_return_code);118 119	if (h_return_code == H_CLOSED)120		rc = true;121 122	return rc;123}124 125/**126 * ibmvscsis_unregister_command_q() - Helper Function-Unregister Command Queue127 * @vscsi:	Pointer to our adapter structure128 *129 * This function calls h_free_q then frees the interrupt bit etc.130 * It must release the lock before doing so because of the time it can take131 * for h_free_crq in PHYP132 * NOTE: * the caller must make sure that state and or flags will prevent133 *	   interrupt handler from scheduling work.134 *       * anyone calling this function may need to set the CRQ_CLOSED flag135 *	   we can't do it here, because we don't have the lock136 *137 * EXECUTION ENVIRONMENT:138 *	Process level139 */140static long ibmvscsis_unregister_command_q(struct scsi_info *vscsi)141{142	long qrc;143	long rc = ADAPT_SUCCESS;144	int ticks = 0;145 146	do {147		qrc = h_free_crq(vscsi->dds.unit_id);148		switch (qrc) {149		case H_SUCCESS:150			spin_lock_bh(&vscsi->intr_lock);151			vscsi->flags &= ~PREP_FOR_SUSPEND_FLAGS;152			spin_unlock_bh(&vscsi->intr_lock);153			break;154 155		case H_HARDWARE:156		case H_PARAMETER:157			dev_err(&vscsi->dev, "unregister_command_q: error from h_free_crq %ld\n",158				qrc);159			rc = ERROR;160			break;161 162		case H_BUSY:163		case H_LONG_BUSY_ORDER_1_MSEC:164			/* msleep not good for small values */165			usleep_range(1000, 2000);166			ticks += 1;167			break;168		case H_LONG_BUSY_ORDER_10_MSEC:169			usleep_range(10000, 20000);170			ticks += 10;171			break;172		case H_LONG_BUSY_ORDER_100_MSEC:173			msleep(100);174			ticks += 100;175			break;176		case H_LONG_BUSY_ORDER_1_SEC:177			ssleep(1);178			ticks += 1000;179			break;180		case H_LONG_BUSY_ORDER_10_SEC:181			ssleep(10);182			ticks += 10000;183			break;184		case H_LONG_BUSY_ORDER_100_SEC:185			ssleep(100);186			ticks += 100000;187			break;188		default:189			dev_err(&vscsi->dev, "unregister_command_q: unknown error %ld from h_free_crq\n",190				qrc);191			rc = ERROR;192			break;193		}194 195		/*196		 * dont wait more then 300 seconds197		 * ticks are in milliseconds more or less198		 */199		if (ticks > 300000 && qrc != H_SUCCESS) {200			rc = ERROR;201			dev_err(&vscsi->dev, "Excessive wait for h_free_crq\n");202		}203	} while (qrc != H_SUCCESS && rc == ADAPT_SUCCESS);204 205	dev_dbg(&vscsi->dev, "Freeing CRQ: phyp rc %ld, rc %ld\n", qrc, rc);206 207	return rc;208}209 210/**211 * ibmvscsis_delete_client_info() - Helper function to Delete Client Info212 * @vscsi:	Pointer to our adapter structure213 * @client_closed:	True if client closed its queue214 *215 * Deletes information specific to the client when the client goes away216 *217 * EXECUTION ENVIRONMENT:218 *	Interrupt or Process219 */220static void ibmvscsis_delete_client_info(struct scsi_info *vscsi,221					 bool client_closed)222{223	vscsi->client_cap = 0;224 225	/*226	 * Some things we don't want to clear if we're closing the queue,227	 * because some clients don't resend the host handshake when they228	 * get a transport event.229	 */230	if (client_closed)231		vscsi->client_data.os_type = 0;232}233 234/**235 * ibmvscsis_free_command_q() - Free Command Queue236 * @vscsi:	Pointer to our adapter structure237 *238 * This function calls unregister_command_q, then clears interrupts and239 * any pending interrupt acknowledgments associated with the command q.240 * It also clears memory if there is no error.241 *242 * PHYP did not meet the PAPR architecture so that we must give up the243 * lock. This causes a timing hole regarding state change.  To close the244 * hole this routine does accounting on any change that occurred during245 * the time the lock is not held.246 * NOTE: must give up and then acquire the interrupt lock, the caller must247 *	 make sure that state and or flags will prevent interrupt handler from248 *	 scheduling work.249 *250 * EXECUTION ENVIRONMENT:251 *	Process level, interrupt lock is held252 */253static long ibmvscsis_free_command_q(struct scsi_info *vscsi)254{255	int bytes;256	u32 flags_under_lock;257	u16 state_under_lock;258	long rc = ADAPT_SUCCESS;259 260	if (!(vscsi->flags & CRQ_CLOSED)) {261		vio_disable_interrupts(vscsi->dma_dev);262 263		state_under_lock = vscsi->new_state;264		flags_under_lock = vscsi->flags;265		vscsi->phyp_acr_state = 0;266		vscsi->phyp_acr_flags = 0;267 268		spin_unlock_bh(&vscsi->intr_lock);269		rc = ibmvscsis_unregister_command_q(vscsi);270		spin_lock_bh(&vscsi->intr_lock);271 272		if (state_under_lock != vscsi->new_state)273			vscsi->phyp_acr_state = vscsi->new_state;274 275		vscsi->phyp_acr_flags = ((~flags_under_lock) & vscsi->flags);276 277		if (rc == ADAPT_SUCCESS) {278			bytes = vscsi->cmd_q.size * PAGE_SIZE;279			memset(vscsi->cmd_q.base_addr, 0, bytes);280			vscsi->cmd_q.index = 0;281			vscsi->flags |= CRQ_CLOSED;282 283			ibmvscsis_delete_client_info(vscsi, false);284		}285 286		dev_dbg(&vscsi->dev, "free_command_q: flags 0x%x, state 0x%hx, acr_flags 0x%x, acr_state 0x%hx\n",287			vscsi->flags, vscsi->state, vscsi->phyp_acr_flags,288			vscsi->phyp_acr_state);289	}290	return rc;291}292 293/**294 * ibmvscsis_cmd_q_dequeue() - Get valid Command element295 * @mask:	Mask to use in case index wraps296 * @current_index:	Current index into command queue297 * @base_addr:	Pointer to start of command queue298 *299 * Returns a pointer to a valid command element or NULL, if the command300 * queue is empty301 *302 * EXECUTION ENVIRONMENT:303 *	Interrupt environment, interrupt lock held304 */305static struct viosrp_crq *ibmvscsis_cmd_q_dequeue(uint mask,306						  uint *current_index,307						  struct viosrp_crq *base_addr)308{309	struct viosrp_crq *ptr;310 311	ptr = base_addr + *current_index;312 313	if (ptr->valid) {314		*current_index = (*current_index + 1) & mask;315		dma_rmb();316	} else {317		ptr = NULL;318	}319 320	return ptr;321}322 323/**324 * ibmvscsis_send_init_message() - send initialize message to the client325 * @vscsi:	Pointer to our adapter structure326 * @format:	Which Init Message format to send327 *328 * EXECUTION ENVIRONMENT:329 *	Interrupt environment interrupt lock held330 */331static long ibmvscsis_send_init_message(struct scsi_info *vscsi, u8 format)332{333	struct viosrp_crq *crq;334	u64 buffer[2] = { 0, 0 };335	long rc;336 337	crq = (struct viosrp_crq *)&buffer;338	crq->valid = VALID_INIT_MSG;339	crq->format = format;340	rc = h_send_crq(vscsi->dds.unit_id, cpu_to_be64(buffer[MSG_HI]),341			cpu_to_be64(buffer[MSG_LOW]));342 343	return rc;344}345 346/**347 * ibmvscsis_check_init_msg() - Check init message valid348 * @vscsi:	Pointer to our adapter structure349 * @format:	Pointer to return format of Init Message, if any.350 *		Set to UNUSED_FORMAT if no Init Message in queue.351 *352 * Checks if an initialize message was queued by the initiatior353 * after the queue was created and before the interrupt was enabled.354 *355 * EXECUTION ENVIRONMENT:356 *	Process level only, interrupt lock held357 */358static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format)359{360	struct viosrp_crq *crq;361	long rc = ADAPT_SUCCESS;362 363	crq = ibmvscsis_cmd_q_dequeue(vscsi->cmd_q.mask, &vscsi->cmd_q.index,364				      vscsi->cmd_q.base_addr);365	if (!crq) {366		*format = (uint)UNUSED_FORMAT;367	} else if (crq->valid == VALID_INIT_MSG && crq->format == INIT_MSG) {368		*format = (uint)INIT_MSG;369		crq->valid = INVALIDATE_CMD_RESP_EL;370		dma_rmb();371 372		/*373		 * the caller has ensured no initialize message was374		 * sent after the queue was375		 * created so there should be no other message on the queue.376		 */377		crq = ibmvscsis_cmd_q_dequeue(vscsi->cmd_q.mask,378					      &vscsi->cmd_q.index,379					      vscsi->cmd_q.base_addr);380		if (crq) {381			*format = (uint)(crq->format);382			rc = ERROR;383			crq->valid = INVALIDATE_CMD_RESP_EL;384			dma_rmb();385		}386	} else {387		*format = (uint)(crq->format);388		rc = ERROR;389		crq->valid = INVALIDATE_CMD_RESP_EL;390		dma_rmb();391	}392 393	return rc;394}395 396/**397 * ibmvscsis_disconnect() - Helper function to disconnect398 * @work:	Pointer to work_struct, gives access to our adapter structure399 *400 * An error has occurred or the driver received a Transport event,401 * and the driver is requesting that the command queue be de-registered402 * in a safe manner. If there is no outstanding I/O then we can stop the403 * queue. If we are restarting the queue it will be reflected in the404 * the state of the adapter.405 *406 * EXECUTION ENVIRONMENT:407 *	Process environment408 */409static void ibmvscsis_disconnect(struct work_struct *work)410{411	struct scsi_info *vscsi = container_of(work, struct scsi_info,412					       proc_work);413	u16 new_state;414	bool wait_idle = false;415 416	spin_lock_bh(&vscsi->intr_lock);417	new_state = vscsi->new_state;418	vscsi->new_state = 0;419 420	vscsi->flags |= DISCONNECT_SCHEDULED;421	vscsi->flags &= ~SCHEDULE_DISCONNECT;422 423	dev_dbg(&vscsi->dev, "disconnect: flags 0x%x, state 0x%hx\n",424		vscsi->flags, vscsi->state);425 426	/*427	 * check which state we are in and see if we428	 * should transitition to the new state429	 */430	switch (vscsi->state) {431	/* Should never be called while in this state. */432	case NO_QUEUE:433	/*434	 * Can never transition from this state;435	 * igonore errors and logout.436	 */437	case UNCONFIGURING:438		break;439 440	/* can transition from this state to UNCONFIGURING */441	case ERR_DISCONNECT:442		if (new_state == UNCONFIGURING)443			vscsi->state = new_state;444		break;445 446	/*447	 * Can transition from this state to unconfiguring448	 * or err disconnect.449	 */450	case ERR_DISCONNECT_RECONNECT:451		switch (new_state) {452		case UNCONFIGURING:453		case ERR_DISCONNECT:454			vscsi->state = new_state;455			break;456 457		case WAIT_IDLE:458			break;459		default:460			break;461		}462		break;463 464	/* can transition from this state to UNCONFIGURING */465	case ERR_DISCONNECTED:466		if (new_state == UNCONFIGURING)467			vscsi->state = new_state;468		break;469 470	case WAIT_ENABLED:471		switch (new_state) {472		case UNCONFIGURING:473			vscsi->state = new_state;474			vscsi->flags |= RESPONSE_Q_DOWN;475			vscsi->flags &= ~(SCHEDULE_DISCONNECT |476					  DISCONNECT_SCHEDULED);477			dma_rmb();478			if (vscsi->flags & CFG_SLEEPING) {479				vscsi->flags &= ~CFG_SLEEPING;480				complete(&vscsi->unconfig);481			}482			break;483 484		/* should never happen */485		case ERR_DISCONNECT:486		case ERR_DISCONNECT_RECONNECT:487		case WAIT_IDLE:488			dev_err(&vscsi->dev, "disconnect: invalid state %d for WAIT_IDLE\n",489				vscsi->state);490			break;491		}492		break;493 494	case WAIT_IDLE:495		switch (new_state) {496		case UNCONFIGURING:497			vscsi->flags |= RESPONSE_Q_DOWN;498			vscsi->state = new_state;499			vscsi->flags &= ~(SCHEDULE_DISCONNECT |500					  DISCONNECT_SCHEDULED);501			ibmvscsis_free_command_q(vscsi);502			break;503		case ERR_DISCONNECT:504		case ERR_DISCONNECT_RECONNECT:505			vscsi->state = new_state;506			break;507		}508		break;509 510	/*511	 * Initiator has not done a successful srp login512	 * or has done a successful srp logout ( adapter was not513	 * busy). In the first case there can be responses queued514	 * waiting for space on the initiators response queue (MAD)515	 * The second case the adapter is idle. Assume the worse case,516	 * i.e. the second case.517	 */518	case WAIT_CONNECTION:519	case CONNECTED:520	case SRP_PROCESSING:521		wait_idle = true;522		vscsi->state = new_state;523		break;524 525	/* can transition from this state to UNCONFIGURING */526	case UNDEFINED:527		if (new_state == UNCONFIGURING)528			vscsi->state = new_state;529		break;530	default:531		break;532	}533 534	if (wait_idle) {535		dev_dbg(&vscsi->dev, "disconnect start wait, active %d, sched %d\n",536			(int)list_empty(&vscsi->active_q),537			(int)list_empty(&vscsi->schedule_q));538		if (!list_empty(&vscsi->active_q) ||539		    !list_empty(&vscsi->schedule_q)) {540			vscsi->flags |= WAIT_FOR_IDLE;541			dev_dbg(&vscsi->dev, "disconnect flags 0x%x\n",542				vscsi->flags);543			/*544			 * This routine is can not be called with the interrupt545			 * lock held.546			 */547			spin_unlock_bh(&vscsi->intr_lock);548			wait_for_completion(&vscsi->wait_idle);549			spin_lock_bh(&vscsi->intr_lock);550		}551		dev_dbg(&vscsi->dev, "disconnect stop wait\n");552 553		ibmvscsis_adapter_idle(vscsi);554	}555 556	spin_unlock_bh(&vscsi->intr_lock);557}558 559/**560 * ibmvscsis_post_disconnect() - Schedule the disconnect561 * @vscsi:	Pointer to our adapter structure562 * @new_state:	State to move to after disconnecting563 * @flag_bits:	Flags to turn on in adapter structure564 *565 * If it's already been scheduled, then see if we need to "upgrade"566 * the new state (if the one passed in is more "severe" than the567 * previous one).568 *569 * PRECONDITION:570 *	interrupt lock is held571 */572static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state,573				      uint flag_bits)574{575	uint state;576 577	/* check the validity of the new state */578	switch (new_state) {579	case UNCONFIGURING:580	case ERR_DISCONNECT:581	case ERR_DISCONNECT_RECONNECT:582	case WAIT_IDLE:583		break;584 585	default:586		dev_err(&vscsi->dev, "post_disconnect: Invalid new state %d\n",587			new_state);588		return;589	}590 591	vscsi->flags |= flag_bits;592 593	dev_dbg(&vscsi->dev, "post_disconnect: new_state 0x%x, flag_bits 0x%x, vscsi->flags 0x%x, state %hx\n",594		new_state, flag_bits, vscsi->flags, vscsi->state);595 596	if (!(vscsi->flags & (DISCONNECT_SCHEDULED | SCHEDULE_DISCONNECT))) {597		vscsi->flags |= SCHEDULE_DISCONNECT;598		vscsi->new_state = new_state;599 600		INIT_WORK(&vscsi->proc_work, ibmvscsis_disconnect);601		(void)queue_work(vscsi->work_q, &vscsi->proc_work);602	} else {603		if (vscsi->new_state)604			state = vscsi->new_state;605		else606			state = vscsi->state;607 608		switch (state) {609		case NO_QUEUE:610		case UNCONFIGURING:611			break;612 613		case ERR_DISCONNECTED:614		case ERR_DISCONNECT:615		case UNDEFINED:616			if (new_state == UNCONFIGURING)617				vscsi->new_state = new_state;618			break;619 620		case ERR_DISCONNECT_RECONNECT:621			switch (new_state) {622			case UNCONFIGURING:623			case ERR_DISCONNECT:624				vscsi->new_state = new_state;625				break;626			default:627				break;628			}629			break;630 631		case WAIT_ENABLED:632		case WAIT_IDLE:633		case WAIT_CONNECTION:634		case CONNECTED:635		case SRP_PROCESSING:636			vscsi->new_state = new_state;637			break;638 639		default:640			break;641		}642	}643 644	dev_dbg(&vscsi->dev, "Leaving post_disconnect: flags 0x%x, new_state 0x%x\n",645		vscsi->flags, vscsi->new_state);646}647 648/**649 * ibmvscsis_handle_init_compl_msg() - Respond to an Init Complete Message650 * @vscsi:	Pointer to our adapter structure651 *652 * Must be called with interrupt lock held.653 */654static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi)655{656	long rc = ADAPT_SUCCESS;657 658	switch (vscsi->state) {659	case NO_QUEUE:660	case ERR_DISCONNECT:661	case ERR_DISCONNECT_RECONNECT:662	case ERR_DISCONNECTED:663	case UNCONFIGURING:664	case UNDEFINED:665		rc = ERROR;666		break;667 668	case WAIT_CONNECTION:669		vscsi->state = CONNECTED;670		break;671 672	case WAIT_IDLE:673	case SRP_PROCESSING:674	case CONNECTED:675	case WAIT_ENABLED:676	default:677		rc = ERROR;678		dev_err(&vscsi->dev, "init_msg: invalid state %d to get init compl msg\n",679			vscsi->state);680		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);681		break;682	}683 684	return rc;685}686 687/**688 * ibmvscsis_handle_init_msg() - Respond to an Init Message689 * @vscsi:	Pointer to our adapter structure690 *691 * Must be called with interrupt lock held.692 */693static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi)694{695	long rc = ADAPT_SUCCESS;696 697	switch (vscsi->state) {698	case WAIT_CONNECTION:699		rc = ibmvscsis_send_init_message(vscsi, INIT_COMPLETE_MSG);700		switch (rc) {701		case H_SUCCESS:702			vscsi->state = CONNECTED;703			break;704 705		case H_PARAMETER:706			dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n",707				rc);708			ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);709			break;710 711		case H_DROPPED:712			dev_err(&vscsi->dev, "init_msg: failed to send, rc %ld\n",713				rc);714			rc = ERROR;715			ibmvscsis_post_disconnect(vscsi,716						  ERR_DISCONNECT_RECONNECT, 0);717			break;718 719		case H_CLOSED:720			dev_warn(&vscsi->dev, "init_msg: failed to send, rc %ld\n",721				 rc);722			rc = 0;723			break;724		}725		break;726 727	case UNDEFINED:728		rc = ERROR;729		break;730 731	case UNCONFIGURING:732		break;733 734	case WAIT_ENABLED:735	case CONNECTED:736	case SRP_PROCESSING:737	case WAIT_IDLE:738	case NO_QUEUE:739	case ERR_DISCONNECT:740	case ERR_DISCONNECT_RECONNECT:741	case ERR_DISCONNECTED:742	default:743		rc = ERROR;744		dev_err(&vscsi->dev, "init_msg: invalid state %d to get init msg\n",745			vscsi->state);746		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);747		break;748	}749 750	return rc;751}752 753/**754 * ibmvscsis_init_msg() - Respond to an init message755 * @vscsi:	Pointer to our adapter structure756 * @crq:	Pointer to CRQ element containing the Init Message757 *758 * EXECUTION ENVIRONMENT:759 *	Interrupt, interrupt lock held760 */761static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq)762{763	long rc = ADAPT_SUCCESS;764 765	dev_dbg(&vscsi->dev, "init_msg: state 0x%hx\n", vscsi->state);766 767	rc = h_vioctl(vscsi->dds.unit_id, H_GET_PARTNER_INFO,768		      (u64)vscsi->map_ioba | ((u64)PAGE_SIZE << 32), 0, 0, 0,769		      0);770	if (rc == H_SUCCESS) {771		vscsi->client_data.partition_number =772			be64_to_cpu(*(u64 *)vscsi->map_buf);773		dev_dbg(&vscsi->dev, "init_msg, part num %d\n",774			vscsi->client_data.partition_number);775	} else {776		dev_dbg(&vscsi->dev, "init_msg h_vioctl rc %ld\n", rc);777		rc = ADAPT_SUCCESS;778	}779 780	if (crq->format == INIT_MSG) {781		rc = ibmvscsis_handle_init_msg(vscsi);782	} else if (crq->format == INIT_COMPLETE_MSG) {783		rc = ibmvscsis_handle_init_compl_msg(vscsi);784	} else {785		rc = ERROR;786		dev_err(&vscsi->dev, "init_msg: invalid format %d\n",787			(uint)crq->format);788		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);789	}790 791	return rc;792}793 794/**795 * ibmvscsis_establish_new_q() - Establish new CRQ queue796 * @vscsi:	Pointer to our adapter structure797 *798 * Must be called with interrupt lock held.799 */800static long ibmvscsis_establish_new_q(struct scsi_info *vscsi)801{802	long rc = ADAPT_SUCCESS;803	uint format;804 805	rc = h_vioctl(vscsi->dds.unit_id, H_ENABLE_PREPARE_FOR_SUSPEND, 30000,806		      0, 0, 0, 0);807	if (rc == H_SUCCESS)808		vscsi->flags |= PREP_FOR_SUSPEND_ENABLED;809	else if (rc != H_NOT_FOUND)810		dev_err(&vscsi->dev, "Error from Enable Prepare for Suspend: %ld\n",811			rc);812 813	vscsi->flags &= PRESERVE_FLAG_FIELDS;814	vscsi->rsp_q_timer.timer_pops = 0;815	vscsi->debit = 0;816	vscsi->credit = 0;817 818	rc = vio_enable_interrupts(vscsi->dma_dev);819	if (rc) {820		dev_warn(&vscsi->dev, "establish_new_q: failed to enable interrupts, rc %ld\n",821			 rc);822		return rc;823	}824 825	rc = ibmvscsis_check_init_msg(vscsi, &format);826	if (rc) {827		dev_err(&vscsi->dev, "establish_new_q: check_init_msg failed, rc %ld\n",828			rc);829		return rc;830	}831 832	if (format == UNUSED_FORMAT) {833		rc = ibmvscsis_send_init_message(vscsi, INIT_MSG);834		switch (rc) {835		case H_SUCCESS:836		case H_DROPPED:837		case H_CLOSED:838			rc = ADAPT_SUCCESS;839			break;840 841		case H_PARAMETER:842		case H_HARDWARE:843			break;844 845		default:846			vscsi->state = UNDEFINED;847			rc = H_HARDWARE;848			break;849		}850	} else if (format == INIT_MSG) {851		rc = ibmvscsis_handle_init_msg(vscsi);852	}853 854	return rc;855}856 857/**858 * ibmvscsis_reset_queue() - Reset CRQ Queue859 * @vscsi:	Pointer to our adapter structure860 *861 * This function calls h_free_q and then calls h_reg_q and does all862 * of the bookkeeping to get us back to where we can communicate.863 *864 * Actually, we don't always call h_free_crq.  A problem was discovered865 * where one partition would close and reopen his queue, which would866 * cause his partner to get a transport event, which would cause him to867 * close and reopen his queue, which would cause the original partition868 * to get a transport event, etc., etc.  To prevent this, we don't869 * actually close our queue if the client initiated the reset, (i.e.870 * either we got a transport event or we have detected that the client's871 * queue is gone)872 *873 * EXECUTION ENVIRONMENT:874 *	Process environment, called with interrupt lock held875 */876static void ibmvscsis_reset_queue(struct scsi_info *vscsi)877{878	int bytes;879	long rc = ADAPT_SUCCESS;880 881	dev_dbg(&vscsi->dev, "reset_queue: flags 0x%x\n", vscsi->flags);882 883	/* don't reset, the client did it for us */884	if (vscsi->flags & (CLIENT_FAILED | TRANS_EVENT)) {885		vscsi->flags &= PRESERVE_FLAG_FIELDS;886		vscsi->rsp_q_timer.timer_pops = 0;887		vscsi->debit = 0;888		vscsi->credit = 0;889		vscsi->state = WAIT_CONNECTION;890		vio_enable_interrupts(vscsi->dma_dev);891	} else {892		rc = ibmvscsis_free_command_q(vscsi);893		if (rc == ADAPT_SUCCESS) {894			vscsi->state = WAIT_CONNECTION;895 896			bytes = vscsi->cmd_q.size * PAGE_SIZE;897			rc = h_reg_crq(vscsi->dds.unit_id,898				       vscsi->cmd_q.crq_token, bytes);899			if (rc == H_CLOSED || rc == H_SUCCESS) {900				rc = ibmvscsis_establish_new_q(vscsi);901			}902 903			if (rc != ADAPT_SUCCESS) {904				dev_dbg(&vscsi->dev, "reset_queue: reg_crq rc %ld\n",905					rc);906 907				vscsi->state = ERR_DISCONNECTED;908				vscsi->flags |= RESPONSE_Q_DOWN;909				ibmvscsis_free_command_q(vscsi);910			}911		} else {912			vscsi->state = ERR_DISCONNECTED;913			vscsi->flags |= RESPONSE_Q_DOWN;914		}915	}916}917 918/**919 * ibmvscsis_free_cmd_resources() - Free command resources920 * @vscsi:	Pointer to our adapter structure921 * @cmd:	Command which is not longer in use922 *923 * Must be called with interrupt lock held.924 */925static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi,926					 struct ibmvscsis_cmd *cmd)927{928	struct iu_entry *iue = cmd->iue;929 930	switch (cmd->type) {931	case TASK_MANAGEMENT:932	case SCSI_CDB:933		/*934		 * When the queue goes down this value is cleared, so it935		 * cannot be cleared in this general purpose function.936		 */937		if (vscsi->debit)938			vscsi->debit -= 1;939		break;940	case ADAPTER_MAD:941		vscsi->flags &= ~PROCESSING_MAD;942		break;943	case UNSET_TYPE:944		break;945	default:946		dev_err(&vscsi->dev, "free_cmd_resources unknown type %d\n",947			cmd->type);948		break;949	}950 951	cmd->iue = NULL;952	list_add_tail(&cmd->list, &vscsi->free_cmd);953	srp_iu_put(iue);954 955	if (list_empty(&vscsi->active_q) && list_empty(&vscsi->schedule_q) &&956	    list_empty(&vscsi->waiting_rsp) && (vscsi->flags & WAIT_FOR_IDLE)) {957		vscsi->flags &= ~WAIT_FOR_IDLE;958		complete(&vscsi->wait_idle);959	}960}961 962/**963 * ibmvscsis_ready_for_suspend() - Helper function to call VIOCTL964 * @vscsi:	Pointer to our adapter structure965 * @idle:	Indicates whether we were called from adapter_idle.  This966 *		is important to know if we need to do a disconnect, since if967 *		we're called from adapter_idle, we're still processing the968 *		current disconnect, so we can't just call post_disconnect.969 *970 * This function is called when the adapter is idle when phyp has sent971 * us a Prepare for Suspend Transport Event.972 *973 * EXECUTION ENVIRONMENT:974 *	Process or interrupt environment called with interrupt lock held975 */976static long ibmvscsis_ready_for_suspend(struct scsi_info *vscsi, bool idle)977{978	long rc = 0;979	struct viosrp_crq *crq;980 981	/* See if there is a Resume event in the queue */982	crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;983 984	dev_dbg(&vscsi->dev, "ready_suspend: flags 0x%x, state 0x%hx crq_valid:%x\n",985		vscsi->flags, vscsi->state, (int)crq->valid);986 987	if (!(vscsi->flags & PREP_FOR_SUSPEND_ABORTED) && !(crq->valid)) {988		rc = h_vioctl(vscsi->dds.unit_id, H_READY_FOR_SUSPEND, 0, 0, 0,989			      0, 0);990		if (rc) {991			dev_err(&vscsi->dev, "Ready for Suspend Vioctl failed: %ld\n",992				rc);993			rc = 0;994		}995	} else if (((vscsi->flags & PREP_FOR_SUSPEND_OVERWRITE) &&996		    (vscsi->flags & PREP_FOR_SUSPEND_ABORTED)) ||997		   ((crq->valid) && ((crq->valid != VALID_TRANS_EVENT) ||998				     (crq->format != RESUME_FROM_SUSP)))) {999		if (idle) {1000			vscsi->state = ERR_DISCONNECT_RECONNECT;1001			ibmvscsis_reset_queue(vscsi);1002			rc = -1;1003		} else if (vscsi->state == CONNECTED) {1004			ibmvscsis_post_disconnect(vscsi,1005						  ERR_DISCONNECT_RECONNECT, 0);1006		}1007 1008		vscsi->flags &= ~PREP_FOR_SUSPEND_OVERWRITE;1009 1010		if ((crq->valid) && ((crq->valid != VALID_TRANS_EVENT) ||1011				     (crq->format != RESUME_FROM_SUSP)))1012			dev_err(&vscsi->dev, "Invalid element in CRQ after Prepare for Suspend");1013	}1014 1015	vscsi->flags &= ~(PREP_FOR_SUSPEND_PENDING | PREP_FOR_SUSPEND_ABORTED);1016 1017	return rc;1018}1019 1020/**1021 * ibmvscsis_trans_event() - Handle a Transport Event1022 * @vscsi:	Pointer to our adapter structure1023 * @crq:	Pointer to CRQ entry containing the Transport Event1024 *1025 * Do the logic to close the I_T nexus.  This function may not1026 * behave to specification.1027 *1028 * EXECUTION ENVIRONMENT:1029 *	Interrupt, interrupt lock held1030 */1031static long ibmvscsis_trans_event(struct scsi_info *vscsi,1032				  struct viosrp_crq *crq)1033{1034	long rc = ADAPT_SUCCESS;1035 1036	dev_dbg(&vscsi->dev, "trans_event: format %d, flags 0x%x, state 0x%hx\n",1037		(int)crq->format, vscsi->flags, vscsi->state);1038 1039	switch (crq->format) {1040	case MIGRATED:1041	case PARTNER_FAILED:1042	case PARTNER_DEREGISTER:1043		ibmvscsis_delete_client_info(vscsi, true);1044		if (crq->format == MIGRATED)1045			vscsi->flags &= ~PREP_FOR_SUSPEND_OVERWRITE;1046		switch (vscsi->state) {1047		case NO_QUEUE:1048		case ERR_DISCONNECTED:1049		case UNDEFINED:1050			break;1051 1052		case UNCONFIGURING:1053			vscsi->flags |= (RESPONSE_Q_DOWN | TRANS_EVENT);1054			break;1055 1056		case WAIT_ENABLED:1057			break;1058 1059		case WAIT_CONNECTION:1060			break;1061 1062		case CONNECTED:1063			ibmvscsis_post_disconnect(vscsi, WAIT_IDLE,1064						  (RESPONSE_Q_DOWN |1065						   TRANS_EVENT));1066			break;1067 1068		case SRP_PROCESSING:1069			if ((vscsi->debit > 0) ||1070			    !list_empty(&vscsi->schedule_q) ||1071			    !list_empty(&vscsi->waiting_rsp) ||1072			    !list_empty(&vscsi->active_q)) {1073				dev_dbg(&vscsi->dev, "debit %d, sched %d, wait %d, active %d\n",1074					vscsi->debit,1075					(int)list_empty(&vscsi->schedule_q),1076					(int)list_empty(&vscsi->waiting_rsp),1077					(int)list_empty(&vscsi->active_q));1078				dev_warn(&vscsi->dev, "connection lost with outstanding work\n");1079			} else {1080				dev_dbg(&vscsi->dev, "trans_event: SRP Processing, but no outstanding work\n");1081			}1082 1083			ibmvscsis_post_disconnect(vscsi, WAIT_IDLE,1084						  (RESPONSE_Q_DOWN |1085						   TRANS_EVENT));1086			break;1087 1088		case ERR_DISCONNECT:1089		case ERR_DISCONNECT_RECONNECT:1090		case WAIT_IDLE:1091			vscsi->flags |= (RESPONSE_Q_DOWN | TRANS_EVENT);1092			break;1093		}1094		break;1095 1096	case PREPARE_FOR_SUSPEND:1097		dev_dbg(&vscsi->dev, "Prep for Suspend, crq status = 0x%x\n",1098			(int)crq->status);1099		switch (vscsi->state) {1100		case ERR_DISCONNECTED:1101		case WAIT_CONNECTION:1102		case CONNECTED:1103			ibmvscsis_ready_for_suspend(vscsi, false);1104			break;1105		case SRP_PROCESSING:1106			vscsi->resume_state = vscsi->state;1107			vscsi->flags |= PREP_FOR_SUSPEND_PENDING;1108			if (crq->status == CRQ_ENTRY_OVERWRITTEN)1109				vscsi->flags |= PREP_FOR_SUSPEND_OVERWRITE;1110			ibmvscsis_post_disconnect(vscsi, WAIT_IDLE, 0);1111			break;1112		case NO_QUEUE:1113		case UNDEFINED:1114		case UNCONFIGURING:1115		case WAIT_ENABLED:1116		case ERR_DISCONNECT:1117		case ERR_DISCONNECT_RECONNECT:1118		case WAIT_IDLE:1119			dev_err(&vscsi->dev, "Invalid state for Prepare for Suspend Trans Event: 0x%x\n",1120				vscsi->state);1121			break;1122		}1123		break;1124 1125	case RESUME_FROM_SUSP:1126		dev_dbg(&vscsi->dev, "Resume from Suspend, crq status = 0x%x\n",1127			(int)crq->status);1128		if (vscsi->flags & PREP_FOR_SUSPEND_PENDING) {1129			vscsi->flags |= PREP_FOR_SUSPEND_ABORTED;1130		} else {1131			if ((crq->status == CRQ_ENTRY_OVERWRITTEN) ||1132			    (vscsi->flags & PREP_FOR_SUSPEND_OVERWRITE)) {1133				ibmvscsis_post_disconnect(vscsi,1134							  ERR_DISCONNECT_RECONNECT,1135							  0);1136				vscsi->flags &= ~PREP_FOR_SUSPEND_OVERWRITE;1137			}1138		}1139		break;1140 1141	default:1142		rc = ERROR;1143		dev_err(&vscsi->dev, "trans_event: invalid format %d\n",1144			(uint)crq->format);1145		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT,1146					  RESPONSE_Q_DOWN);1147		break;1148	}1149 1150	rc = vscsi->flags & SCHEDULE_DISCONNECT;1151 1152	dev_dbg(&vscsi->dev, "Leaving trans_event: flags 0x%x, state 0x%hx, rc %ld\n",1153		vscsi->flags, vscsi->state, rc);1154 1155	return rc;1156}1157 1158/**1159 * ibmvscsis_poll_cmd_q() - Poll Command Queue1160 * @vscsi:	Pointer to our adapter structure1161 *1162 * Called to handle command elements that may have arrived while1163 * interrupts were disabled.1164 *1165 * EXECUTION ENVIRONMENT:1166 *	intr_lock must be held1167 */1168static void ibmvscsis_poll_cmd_q(struct scsi_info *vscsi)1169{1170	struct viosrp_crq *crq;1171	long rc;1172	bool ack = true;1173	volatile u8 valid;1174 1175	dev_dbg(&vscsi->dev, "poll_cmd_q: flags 0x%x, state 0x%hx, q index %ud\n",1176		vscsi->flags, vscsi->state, vscsi->cmd_q.index);1177 1178	rc = vscsi->flags & SCHEDULE_DISCONNECT;1179	crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;1180	valid = crq->valid;1181	dma_rmb();1182 1183	while (valid) {1184poll_work:1185		vscsi->cmd_q.index =1186			(vscsi->cmd_q.index + 1) & vscsi->cmd_q.mask;1187 1188		if (!rc) {1189			rc = ibmvscsis_parse_command(vscsi, crq);1190		} else {1191			if ((uint)crq->valid == VALID_TRANS_EVENT) {1192				/*1193				 * must service the transport layer events even1194				 * in an error state, dont break out until all1195				 * the consecutive transport events have been1196				 * processed1197				 */1198				rc = ibmvscsis_trans_event(vscsi, crq);1199			} else if (vscsi->flags & TRANS_EVENT) {1200				/*1201				 * if a tranport event has occurred leave1202				 * everything but transport events on the queue1203				 */1204				dev_dbg(&vscsi->dev, "poll_cmd_q, ignoring\n");1205 1206				/*1207				 * need to decrement the queue index so we can1208				 * look at the elment again1209				 */1210				if (vscsi->cmd_q.index)1211					vscsi->cmd_q.index -= 1;1212				else1213					/*1214					 * index is at 0 it just wrapped.1215					 * have it index last element in q1216					 */1217					vscsi->cmd_q.index = vscsi->cmd_q.mask;1218				break;1219			}1220		}1221 1222		crq->valid = INVALIDATE_CMD_RESP_EL;1223 1224		crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;1225		valid = crq->valid;1226		dma_rmb();1227	}1228 1229	if (!rc) {1230		if (ack) {1231			vio_enable_interrupts(vscsi->dma_dev);1232			ack = false;1233			dev_dbg(&vscsi->dev, "poll_cmd_q, reenabling interrupts\n");1234		}1235		valid = crq->valid;1236		dma_rmb();1237		if (valid)1238			goto poll_work;1239	}1240 1241	dev_dbg(&vscsi->dev, "Leaving poll_cmd_q: rc %ld\n", rc);1242}1243 1244/**1245 * ibmvscsis_free_cmd_qs() - Free elements in queue1246 * @vscsi:	Pointer to our adapter structure1247 *1248 * Free all of the elements on all queues that are waiting for1249 * whatever reason.1250 *1251 * PRECONDITION:1252 *	Called with interrupt lock held1253 */1254static void ibmvscsis_free_cmd_qs(struct scsi_info *vscsi)1255{1256	struct ibmvscsis_cmd *cmd, *nxt;1257 1258	dev_dbg(&vscsi->dev, "free_cmd_qs: waiting_rsp empty %d, timer starter %d\n",1259		(int)list_empty(&vscsi->waiting_rsp),1260		vscsi->rsp_q_timer.started);1261 1262	list_for_each_entry_safe(cmd, nxt, &vscsi->waiting_rsp, list) {1263		list_del(&cmd->list);1264		ibmvscsis_free_cmd_resources(vscsi, cmd);1265	}1266}1267 1268/**1269 * ibmvscsis_get_free_cmd() - Get free command from list1270 * @vscsi:	Pointer to our adapter structure1271 *1272 * Must be called with interrupt lock held.1273 */1274static struct ibmvscsis_cmd *ibmvscsis_get_free_cmd(struct scsi_info *vscsi)1275{1276	struct ibmvscsis_cmd *cmd = NULL;1277	struct iu_entry *iue;1278 1279	iue = srp_iu_get(&vscsi->target);1280	if (iue) {1281		cmd = list_first_entry_or_null(&vscsi->free_cmd,1282					       struct ibmvscsis_cmd, list);1283		if (cmd) {1284			if (cmd->abort_cmd)1285				cmd->abort_cmd = NULL;1286			cmd->flags &= ~(DELAY_SEND);1287			list_del(&cmd->list);1288			cmd->iue = iue;1289			cmd->type = UNSET_TYPE;1290			memset(&cmd->se_cmd, 0, sizeof(cmd->se_cmd));1291		} else {1292			srp_iu_put(iue);1293		}1294	}1295 1296	return cmd;1297}1298 1299/**1300 * ibmvscsis_adapter_idle() - Helper function to handle idle adapter1301 * @vscsi:	Pointer to our adapter structure1302 *1303 * This function is called when the adapter is idle when the driver1304 * is attempting to clear an error condition.1305 * The adapter is considered busy if any of its cmd queues1306 * are non-empty. This function can be invoked1307 * from the off level disconnect function.1308 *1309 * EXECUTION ENVIRONMENT:1310 *	Process environment called with interrupt lock held1311 */1312static void ibmvscsis_adapter_idle(struct scsi_info *vscsi)1313{1314	int free_qs = false;1315	long rc = 0;1316 1317	dev_dbg(&vscsi->dev, "adapter_idle: flags 0x%x, state 0x%hx\n",1318		vscsi->flags, vscsi->state);1319 1320	/* Only need to free qs if we're disconnecting from client */1321	if (vscsi->state != WAIT_CONNECTION || vscsi->flags & TRANS_EVENT)1322		free_qs = true;1323 1324	switch (vscsi->state) {1325	case UNCONFIGURING:1326		ibmvscsis_free_command_q(vscsi);1327		dma_rmb();1328		isync();1329		if (vscsi->flags & CFG_SLEEPING) {1330			vscsi->flags &= ~CFG_SLEEPING;1331			complete(&vscsi->unconfig);1332		}1333		break;1334	case ERR_DISCONNECT_RECONNECT:1335		ibmvscsis_reset_queue(vscsi);1336		dev_dbg(&vscsi->dev, "adapter_idle, disc_rec: flags 0x%x\n",1337			vscsi->flags);1338		break;1339 1340	case ERR_DISCONNECT:1341		ibmvscsis_free_command_q(vscsi);1342		vscsi->flags &= ~(SCHEDULE_DISCONNECT | DISCONNECT_SCHEDULED);1343		vscsi->flags |= RESPONSE_Q_DOWN;1344		if (vscsi->tport.enabled)1345			vscsi->state = ERR_DISCONNECTED;1346		else1347			vscsi->state = WAIT_ENABLED;1348		dev_dbg(&vscsi->dev, "adapter_idle, disc: flags 0x%x, state 0x%hx\n",1349			vscsi->flags, vscsi->state);1350		break;1351 1352	case WAIT_IDLE:1353		vscsi->rsp_q_timer.timer_pops = 0;1354		vscsi->debit = 0;1355		vscsi->credit = 0;1356		if (vscsi->flags & PREP_FOR_SUSPEND_PENDING) {1357			vscsi->state = vscsi->resume_state;1358			vscsi->resume_state = 0;1359			rc = ibmvscsis_ready_for_suspend(vscsi, true);1360			vscsi->flags &= ~DISCONNECT_SCHEDULED;1361			if (rc)1362				break;1363		} else if (vscsi->flags & TRANS_EVENT) {1364			vscsi->state = WAIT_CONNECTION;1365			vscsi->flags &= PRESERVE_FLAG_FIELDS;1366		} else {1367			vscsi->state = CONNECTED;1368			vscsi->flags &= ~DISCONNECT_SCHEDULED;1369		}1370 1371		dev_dbg(&vscsi->dev, "adapter_idle, wait: flags 0x%x, state 0x%hx\n",1372			vscsi->flags, vscsi->state);1373		ibmvscsis_poll_cmd_q(vscsi);1374		break;1375 1376	case ERR_DISCONNECTED:1377		vscsi->flags &= ~DISCONNECT_SCHEDULED;1378		dev_dbg(&vscsi->dev, "adapter_idle, disconnected: flags 0x%x, state 0x%hx\n",1379			vscsi->flags, vscsi->state);1380		break;1381 1382	default:1383		dev_err(&vscsi->dev, "adapter_idle: in invalid state %d\n",1384			vscsi->state);1385		break;1386	}1387 1388	if (free_qs)1389		ibmvscsis_free_cmd_qs(vscsi);1390 1391	/*1392	 * There is a timing window where we could lose a disconnect request.1393	 * The known path to this window occurs during the DISCONNECT_RECONNECT1394	 * case above: reset_queue calls free_command_q, which will release the1395	 * interrupt lock.  During that time, a new post_disconnect call can be1396	 * made with a "more severe" state (DISCONNECT or UNCONFIGURING).1397	 * Because the DISCONNECT_SCHEDULED flag is already set, post_disconnect1398	 * will only set the new_state.  Now free_command_q reacquires the intr1399	 * lock and clears the DISCONNECT_SCHEDULED flag (using PRESERVE_FLAG_1400	 * FIELDS), and the disconnect is lost.  This is particularly bad when1401	 * the new disconnect was for UNCONFIGURING, since the unconfigure hangs1402	 * forever.1403	 * Fix is that free command queue sets acr state and acr flags if there1404	 * is a change under the lock1405	 * note free command queue writes to this state it clears it1406	 * before releasing the lock, different drivers call the free command1407	 * queue different times so dont initialize above1408	 */1409	if (vscsi->phyp_acr_state != 0)	{1410		/*1411		 * set any bits in flags that may have been cleared by1412		 * a call to free command queue in switch statement1413		 * or reset queue1414		 */1415		vscsi->flags |= vscsi->phyp_acr_flags;1416		ibmvscsis_post_disconnect(vscsi, vscsi->phyp_acr_state, 0);1417		vscsi->phyp_acr_state = 0;1418		vscsi->phyp_acr_flags = 0;1419 1420		dev_dbg(&vscsi->dev, "adapter_idle: flags 0x%x, state 0x%hx, acr_flags 0x%x, acr_state 0x%hx\n",1421			vscsi->flags, vscsi->state, vscsi->phyp_acr_flags,1422			vscsi->phyp_acr_state);1423	}1424 1425	dev_dbg(&vscsi->dev, "Leaving adapter_idle: flags 0x%x, state 0x%hx, new_state 0x%x\n",1426		vscsi->flags, vscsi->state, vscsi->new_state);1427}1428 1429/**1430 * ibmvscsis_copy_crq_packet() - Copy CRQ Packet1431 * @vscsi:	Pointer to our adapter structure1432 * @cmd:	Pointer to command element to use to process the request1433 * @crq:	Pointer to CRQ entry containing the request1434 *1435 * Copy the srp information unit from the hosted1436 * partition using remote dma1437 *1438 * EXECUTION ENVIRONMENT:1439 *	Interrupt, interrupt lock held1440 */1441static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi,1442				      struct ibmvscsis_cmd *cmd,1443				      struct viosrp_crq *crq)1444{1445	struct iu_entry *iue = cmd->iue;1446	long rc = 0;1447	u16 len;1448 1449	len = be16_to_cpu(crq->IU_length);1450	if ((len > SRP_MAX_IU_LEN) || (len == 0)) {1451		dev_err(&vscsi->dev, "copy_crq: Invalid len %d passed", len);1452		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);1453		return SRP_VIOLATION;1454	}1455 1456	rc = h_copy_rdma(len, vscsi->dds.window[REMOTE].liobn,1457			 be64_to_cpu(crq->IU_data_ptr),1458			 vscsi->dds.window[LOCAL].liobn, iue->sbuf->dma);1459 1460	switch (rc) {1461	case H_SUCCESS:1462		cmd->init_time = mftb();1463		iue->remote_token = crq->IU_data_ptr;1464		iue->iu_len = len;1465		dev_dbg(&vscsi->dev, "copy_crq: ioba 0x%llx, init_time 0x%llx\n",1466			be64_to_cpu(crq->IU_data_ptr), cmd->init_time);1467		break;1468	case H_PERMISSION:1469		if (connection_broken(vscsi))1470			ibmvscsis_post_disconnect(vscsi,1471						  ERR_DISCONNECT_RECONNECT,1472						  (RESPONSE_Q_DOWN |1473						   CLIENT_FAILED));1474		else1475			ibmvscsis_post_disconnect(vscsi,1476						  ERR_DISCONNECT_RECONNECT, 0);1477 1478		dev_err(&vscsi->dev, "copy_crq: h_copy_rdma failed, rc %ld\n",1479			rc);1480		break;1481	case H_DEST_PARM:1482	case H_SOURCE_PARM:1483	default:1484		dev_err(&vscsi->dev, "copy_crq: h_copy_rdma failed, rc %ld\n",1485			rc);1486		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);1487		break;1488	}1489 1490	return rc;1491}1492 1493/**1494 * ibmvscsis_adapter_info - Service an Adapter Info MAnagement Data gram1495 * @vscsi:	Pointer to our adapter structure1496 * @iue:	Information Unit containing the Adapter Info MAD request1497 *1498 * EXECUTION ENVIRONMENT:1499 *	Interrupt adapter lock is held1500 */1501static long ibmvscsis_adapter_info(struct scsi_info *vscsi,1502				   struct iu_entry *iue)1503{1504	struct viosrp_adapter_info *mad = &vio_iu(iue)->mad.adapter_info;1505	struct mad_adapter_info_data *info;1506	uint flag_bits = 0;1507	dma_addr_t token;1508	long rc;1509 1510	mad->common.status = cpu_to_be16(VIOSRP_MAD_SUCCESS);1511 1512	if (be16_to_cpu(mad->common.length) > sizeof(*info)) {1513		mad->common.status = cpu_to_be16(VIOSRP_MAD_FAILED);1514		return 0;1515	}1516 1517	info = dma_alloc_coherent(&vscsi->dma_dev->dev, sizeof(*info), &token,1518				  GFP_ATOMIC);1519	if (!info) {1520		dev_err(&vscsi->dev, "bad dma_alloc_coherent %p\n",1521			iue->target);1522		mad->common.status = cpu_to_be16(VIOSRP_MAD_FAILED);1523		return 0;1524	}1525 1526	/* Get remote info */1527	rc = h_copy_rdma(be16_to_cpu(mad->common.length),1528			 vscsi->dds.window[REMOTE].liobn,1529			 be64_to_cpu(mad->buffer),1530			 vscsi->dds.window[LOCAL].liobn, token);1531 1532	if (rc != H_SUCCESS) {1533		if (rc == H_PERMISSION) {1534			if (connection_broken(vscsi))1535				flag_bits = (RESPONSE_Q_DOWN | CLIENT_FAILED);1536		}1537		dev_warn(&vscsi->dev, "adapter_info: h_copy_rdma from client failed, rc %ld\n",1538			 rc);1539		dev_dbg(&vscsi->dev, "adapter_info: ioba 0x%llx, flags 0x%x, flag_bits 0x%x\n",1540			be64_to_cpu(mad->buffer), vscsi->flags, flag_bits);1541		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT,1542					  flag_bits);1543		goto free_dma;1544	}1545 1546	/*1547	 * Copy client info, but ignore partition number, which we1548	 * already got from phyp - unless we failed to get it from1549	 * phyp (e.g. if we're running on a p5 system).1550	 */1551	if (vscsi->client_data.partition_number == 0)1552		vscsi->client_data.partition_number =1553			be32_to_cpu(info->partition_number);1554	strscpy(vscsi->client_data.srp_version, info->srp_version,1555		sizeof(vscsi->client_data.srp_version));1556	strscpy(vscsi->client_data.partition_name, info->partition_name,1557		sizeof(vscsi->client_data.partition_name));1558	vscsi->client_data.mad_version = be32_to_cpu(info->mad_version);1559	vscsi->client_data.os_type = be32_to_cpu(info->os_type);1560 1561	/* Copy our info */1562	strscpy_pad(info->srp_version, SRP_VERSION,1563		    sizeof(info->srp_version));1564	strscpy_pad(info->partition_name, vscsi->dds.partition_name,1565		    sizeof(info->partition_name));1566	info->partition_number = cpu_to_be32(vscsi->dds.partition_num);1567	info->mad_version = cpu_to_be32(MAD_VERSION_1);1568	info->os_type = cpu_to_be32(LINUX);1569	memset(&info->port_max_txu[0], 0, sizeof(info->port_max_txu));1570	info->port_max_txu[0] = cpu_to_be32(MAX_TXU);1571 1572	dma_wmb();1573	rc = h_copy_rdma(sizeof(*info), vscsi->dds.window[LOCAL].liobn,1574			 token, vscsi->dds.window[REMOTE].liobn,1575			 be64_to_cpu(mad->buffer));1576	switch (rc) {1577	case H_SUCCESS:1578		break;1579 1580	case H_SOURCE_PARM:1581	case H_DEST_PARM:1582	case H_PERMISSION:1583		if (connection_broken(vscsi))1584			flag_bits = (RESPONSE_Q_DOWN | CLIENT_FAILED);1585		fallthrough;1586	default:1587		dev_err(&vscsi->dev, "adapter_info: h_copy_rdma to client failed, rc %ld\n",1588			rc);1589		ibmvscsis_post_disconnect(vscsi,1590					  ERR_DISCONNECT_RECONNECT,1591					  flag_bits);1592		break;1593	}1594 1595free_dma:1596	dma_free_coherent(&vscsi->dma_dev->dev, sizeof(*info), info, token);1597	dev_dbg(&vscsi->dev, "Leaving adapter_info, rc %ld\n", rc);1598 1599	return rc;1600}1601 1602/**1603 * ibmvscsis_cap_mad() - Service a Capabilities MAnagement Data gram1604 * @vscsi:	Pointer to our adapter structure1605 * @iue:	Information Unit containing the Capabilities MAD request1606 *1607 * NOTE: if you return an error from this routine you must be1608 * disconnecting or you will cause a hang1609 *1610 * EXECUTION ENVIRONMENT:1611 *	Interrupt called with adapter lock held1612 */1613static int ibmvscsis_cap_mad(struct scsi_info *vscsi, struct iu_entry *iue)1614{1615	struct viosrp_capabilities *mad = &vio_iu(iue)->mad.capabilities;1616	struct capabilities *cap;1617	struct mad_capability_common *common;1618	dma_addr_t token;1619	u16 olen, len, status, min_len, cap_len;1620	u32 flag;1621	uint flag_bits = 0;1622	long rc = 0;1623 1624	olen = be16_to_cpu(mad->common.length);1625	/*1626	 * struct capabilities hardcodes a couple capabilities after the1627	 * header, but the capabilities can actually be in any order.1628	 */1629	min_len = offsetof(struct capabilities, migration);1630	if ((olen < min_len) || (olen > PAGE_SIZE)) {1631		dev_warn(&vscsi->dev, "cap_mad: invalid len %d\n", olen);1632		mad->common.status = cpu_to_be16(VIOSRP_MAD_FAILED);1633		return 0;1634	}1635 1636	cap = dma_alloc_coherent(&vscsi->dma_dev->dev, olen, &token,1637				 GFP_ATOMIC);1638	if (!cap) {1639		dev_err(&vscsi->dev, "bad dma_alloc_coherent %p\n",1640			iue->target);1641		mad->common.status = cpu_to_be16(VIOSRP_MAD_FAILED);1642		return 0;1643	}1644	rc = h_copy_rdma(olen, vscsi->dds.window[REMOTE].liobn,1645			 be64_to_cpu(mad->buffer),1646			 vscsi->dds.window[LOCAL].liobn, token);1647	if (rc == H_SUCCESS) {1648		strscpy_pad(cap->name, dev_name(&vscsi->dma_dev->dev),1649			sizeof(cap->name));1650 1651		len = olen - min_len;1652		status = VIOSRP_MAD_SUCCESS;1653		common = (struct mad_capability_common *)&cap->migration;1654 1655		while ((len > 0) && (status == VIOSRP_MAD_SUCCESS) && !rc) {1656			dev_dbg(&vscsi->dev, "cap_mad: len left %hd, cap type %d, cap len %hd\n",1657				len, be32_to_cpu(common->cap_type),1658				be16_to_cpu(common->length));1659 1660			cap_len = be16_to_cpu(common->length);1661			if (cap_len > len) {1662				dev_err(&vscsi->dev, "cap_mad: cap len mismatch with total len\n");1663				status = VIOSRP_MAD_FAILED;1664				break;1665			}1666 1667			if (cap_len == 0) {1668				dev_err(&vscsi->dev, "cap_mad: cap len is 0\n");1669				status = VIOSRP_MAD_FAILED;1670				break;1671			}1672 1673			switch (common->cap_type) {1674			default:1675				dev_dbg(&vscsi->dev, "cap_mad: unsupported capability\n");1676				common->server_support = 0;1677				flag = cpu_to_be32((u32)CAP_LIST_SUPPORTED);1678				cap->flags &= ~flag;1679				break;1680			}1681 1682			len = len - cap_len;1683			common = (struct mad_capability_common *)1684				((char *)common + cap_len);1685		}1686 1687		mad->common.status = cpu_to_be16(status);1688 1689		dma_wmb();1690		rc = h_copy_rdma(olen, vscsi->dds.window[LOCAL].liobn, token,1691				 vscsi->dds.window[REMOTE].liobn,1692				 be64_to_cpu(mad->buffer));1693 1694		if (rc != H_SUCCESS) {1695			dev_dbg(&vscsi->dev, "cap_mad: failed to copy to client, rc %ld\n",1696				rc);1697 1698			if (rc == H_PERMISSION) {1699				if (connection_broken(vscsi))1700					flag_bits = (RESPONSE_Q_DOWN |1701						     CLIENT_FAILED);1702			}1703 1704			dev_warn(&vscsi->dev, "cap_mad: error copying data to client, rc %ld\n",1705				 rc);1706			ibmvscsis_post_disconnect(vscsi,1707						  ERR_DISCONNECT_RECONNECT,1708						  flag_bits);1709		}1710	}1711 1712	dma_free_coherent(&vscsi->dma_dev->dev, olen, cap, token);1713 1714	dev_dbg(&vscsi->dev, "Leaving cap_mad, rc %ld, client_cap 0x%x\n",1715		rc, vscsi->client_cap);1716 1717	return rc;1718}1719 1720/**1721 * ibmvscsis_process_mad() - Service a MAnagement Data gram1722 * @vscsi:	Pointer to our adapter structure1723 * @iue:	Information Unit containing the MAD request1724 *1725 * Must be called with interrupt lock held.1726 */1727static long ibmvscsis_process_mad(struct scsi_info *vscsi, struct iu_entry *iue)1728{1729	struct mad_common *mad = (struct mad_common *)&vio_iu(iue)->mad;1730	struct viosrp_empty_iu *empty;1731	long rc = ADAPT_SUCCESS;1732 1733	switch (be32_to_cpu(mad->type)) {1734	case VIOSRP_EMPTY_IU_TYPE:1735		empty = &vio_iu(iue)->mad.empty_iu;1736		vscsi->empty_iu_id = be64_to_cpu(empty->buffer);1737		vscsi->empty_iu_tag = be64_to_cpu(empty->common.tag);1738		mad->status = cpu_to_be16(VIOSRP_MAD_SUCCESS);1739		break;1740	case VIOSRP_ADAPTER_INFO_TYPE:1741		rc = ibmvscsis_adapter_info(vscsi, iue);1742		break;1743	case VIOSRP_CAPABILITIES_TYPE:1744		rc = ibmvscsis_cap_mad(vscsi, iue);1745		break;1746	case VIOSRP_ENABLE_FAST_FAIL:1747		if (vscsi->state == CONNECTED) {1748			vscsi->fast_fail = true;1749			mad->status = cpu_to_be16(VIOSRP_MAD_SUCCESS);1750		} else {1751			dev_warn(&vscsi->dev, "fast fail mad sent after login\n");1752			mad->status = cpu_to_be16(VIOSRP_MAD_FAILED);1753		}1754		break;1755	default:1756		mad->status = cpu_to_be16(VIOSRP_MAD_NOT_SUPPORTED);1757		break;1758	}1759 1760	return rc;1761}1762 1763/**1764 * srp_snd_msg_failed() - Handle an error when sending a response1765 * @vscsi:	Pointer to our adapter structure1766 * @rc:		The return code from the h_send_crq command1767 *1768 * Must be called with interrupt lock held.1769 */1770static void srp_snd_msg_failed(struct scsi_info *vscsi, long rc)1771{1772	ktime_t kt;1773 1774	if (rc != H_DROPPED) {1775		ibmvscsis_free_cmd_qs(vscsi);1776 1777		if (rc == H_CLOSED)1778			vscsi->flags |= CLIENT_FAILED;1779 1780		/* don't flag the same problem multiple times */1781		if (!(vscsi->flags & RESPONSE_Q_DOWN)) {1782			vscsi->flags |= RESPONSE_Q_DOWN;1783			if (!(vscsi->state & (ERR_DISCONNECT |1784					      ERR_DISCONNECT_RECONNECT |1785					      ERR_DISCONNECTED | UNDEFINED))) {1786				dev_err(&vscsi->dev, "snd_msg_failed: setting RESPONSE_Q_DOWN, state 0x%hx, flags 0x%x, rc %ld\n",1787					vscsi->state, vscsi->flags, rc);1788			}1789			ibmvscsis_post_disconnect(vscsi,1790						  ERR_DISCONNECT_RECONNECT, 0);1791		}1792		return;1793	}1794 1795	/*1796	 * The response queue is full.1797	 * If the server is processing SRP requests, i.e.1798	 * the client has successfully done an1799	 * SRP_LOGIN, then it will wait forever for room in1800	 * the queue.  However if the system admin1801	 * is attempting to unconfigure the server then one1802	 * or more children will be in a state where1803	 * they are being removed. So if there is even one1804	 * child being removed then the driver assumes1805	 * the system admin is attempting to break the1806	 * connection with the client and MAX_TIMER_POPS1807	 * is honored.1808	 */1809	if ((vscsi->rsp_q_timer.timer_pops < MAX_TIMER_POPS) ||1810	    (vscsi->state == SRP_PROCESSING)) {1811		dev_dbg(&vscsi->dev, "snd_msg_failed: response queue full, flags 0x%x, timer started %d, pops %d\n",1812			vscsi->flags, (int)vscsi->rsp_q_timer.started,1813			vscsi->rsp_q_timer.timer_pops);1814 1815		/*1816		 * Check if the timer is running; if it1817		 * is not then start it up.1818		 */1819		if (!vscsi->rsp_q_timer.started) {1820			if (vscsi->rsp_q_timer.timer_pops <1821			    MAX_TIMER_POPS) {1822				kt = WAIT_NANO_SECONDS;1823			} else {1824				/*1825				 * slide the timeslice if the maximum1826				 * timer pops have already happened1827				 */1828				kt = ktime_set(WAIT_SECONDS, 0);1829			}1830 1831			vscsi->rsp_q_timer.started = true;1832			hrtimer_start(&vscsi->rsp_q_timer.timer, kt,1833				      HRTIMER_MODE_REL);1834		}1835	} else {1836		/*1837		 * TBD: Do we need to worry about this? Need to get1838		 *      remove working.1839		 */1840		/*1841		 * waited a long time and it appears the system admin1842		 * is bring this driver down1843		 */1844		vscsi->flags |= RESPONSE_Q_DOWN;1845		ibmvscsis_free_cmd_qs(vscsi);1846		/*1847		 * if the driver is already attempting to disconnect1848		 * from the client and has already logged an error1849		 * trace this event but don't put it in the error log1850		 */1851		if (!(vscsi->state & (ERR_DISCONNECT |1852				      ERR_DISCONNECT_RECONNECT |1853				      ERR_DISCONNECTED | UNDEFINED))) {1854			dev_err(&vscsi->dev, "client crq full too long\n");1855			ibmvscsis_post_disconnect(vscsi,1856						  ERR_DISCONNECT_RECONNECT,1857						  0);1858		}1859	}1860}1861 1862/**1863 * ibmvscsis_send_messages() - Send a Response1864 * @vscsi:	Pointer to our adapter structure1865 *1866 * Send a response, first checking the waiting queue. Responses are1867 * sent in order they are received. If the response cannot be sent,1868 * because the client queue is full, it stays on the waiting queue.1869 *1870 * PRECONDITION:1871 *	Called with interrupt lock held1872 */1873static void ibmvscsis_send_messages(struct scsi_info *vscsi)1874{1875	struct viosrp_crq empty_crq = { };1876	struct viosrp_crq *crq = &empty_crq;1877	struct ibmvscsis_cmd *cmd, *nxt;1878	long rc = ADAPT_SUCCESS;1879	bool retry = false;1880 1881	if (!(vscsi->flags & RESPONSE_Q_DOWN)) {1882		do {1883			retry = false;1884			list_for_each_entry_safe(cmd, nxt, &vscsi->waiting_rsp,1885						 list) {1886				/*1887				 * Check to make sure abort cmd gets processed1888				 * prior to the abort tmr cmd1889				 */1890				if (cmd->flags & DELAY_SEND)1891					continue;1892 1893				if (cmd->abort_cmd) {1894					retry = true;1895					cmd->abort_cmd->flags &= ~(DELAY_SEND);1896					cmd->abort_cmd = NULL;1897				}1898 1899				/*1900				 * If CMD_T_ABORTED w/o CMD_T_TAS scenarios and1901				 * the case where LIO issued a1902				 * ABORT_TASK: Sending TMR_TASK_DOES_NOT_EXIST1903				 * case then we dont send a response, since it1904				 * was already done.1905				 */1906				if (cmd->se_cmd.transport_state & CMD_T_ABORTED &&1907				    !(cmd->se_cmd.transport_state & CMD_T_TAS)) {1908					list_del(&cmd->list);1909					ibmvscsis_free_cmd_resources(vscsi,1910								     cmd);1911					/*1912					 * With a successfully aborted op1913					 * through LIO we want to increment the1914					 * the vscsi credit so that when we dont1915					 * send a rsp to the original scsi abort1916					 * op (h_send_crq), but the tm rsp to1917					 * the abort is sent, the credit is1918					 * correctly sent with the abort tm rsp.1919					 * We would need 1 for the abort tm rsp1920					 * and 1 credit for the aborted scsi op.1921					 * Thus we need to increment here.1922					 * Also we want to increment the credit1923					 * here because we want to make sure1924					 * cmd is actually released first1925					 * otherwise the client will think it1926					 * it can send a new cmd, and we could1927					 * find ourselves short of cmd elements.1928					 */1929					vscsi->credit += 1;1930				} else {1931					crq->valid = VALID_CMD_RESP_EL;1932					crq->format = cmd->rsp.format;1933 1934					if (cmd->flags & CMD_FAST_FAIL)1935						crq->status = VIOSRP_ADAPTER_FAIL;1936 1937					crq->IU_length = cpu_to_be16(cmd->rsp.len);1938 1939					rc = h_send_crq(vscsi->dma_dev->unit_address,1940							be64_to_cpu(crq->high),1941							be64_to_cpu(cmd->rsp.tag));1942 1943					dev_dbg(&vscsi->dev, "send_messages: cmd %p, tag 0x%llx, rc %ld\n",1944						cmd, be64_to_cpu(cmd->rsp.tag),1945						rc);1946 1947					/* if all ok free up the command1948					 * element resources1949					 */1950					if (rc == H_SUCCESS) {1951						/* some movement has occurred */1952						vscsi->rsp_q_timer.timer_pops = 0;1953						list_del(&cmd->list);1954 1955						ibmvscsis_free_cmd_resources(vscsi,1956									     cmd);1957					} else {1958						srp_snd_msg_failed(vscsi, rc);1959						break;1960					}1961				}1962			}1963		} while (retry);1964 1965		if (!rc) {1966			/*1967			 * The timer could pop with the queue empty.  If1968			 * this happens, rc will always indicate a1969			 * success; clear the pop count.1970			 */1971			vscsi->rsp_q_timer.timer_pops = 0;1972		}1973	} else {1974		ibmvscsis_free_cmd_qs(vscsi);1975	}1976}1977 1978/* Called with intr lock held */1979static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi,1980				    struct ibmvscsis_cmd *cmd,1981				    struct viosrp_crq *crq)1982{1983	struct iu_entry *iue = cmd->iue;1984	struct mad_common *mad = (struct mad_common *)&vio_iu(iue)->mad;1985	uint flag_bits = 0;1986	long rc;1987 1988	dma_wmb();1989	rc = h_copy_rdma(sizeof(struct mad_common),1990			 vscsi->dds.window[LOCAL].liobn, iue->sbuf->dma,1991			 vscsi->dds.window[REMOTE].liobn,1992			 be64_to_cpu(crq->IU_data_ptr));1993	if (!rc) {1994		cmd->rsp.format = VIOSRP_MAD_FORMAT;1995		cmd->rsp.len = sizeof(struct mad_common);1996		cmd->rsp.tag = mad->tag;1997		list_add_tail(&cmd->list, &vscsi->waiting_rsp);1998		ibmvscsis_send_messages(vscsi);1999	} else {2000		dev_dbg(&vscsi->dev, "Error sending mad response, rc %ld\n",2001			rc);2002		if (rc == H_PERMISSION) {2003			if (connection_broken(vscsi))2004				flag_bits = (RESPONSE_Q_DOWN | CLIENT_FAILED);2005		}2006		dev_err(&vscsi->dev, "mad: failed to copy to client, rc %ld\n",2007			rc);2008 2009		ibmvscsis_free_cmd_resources(vscsi, cmd);2010		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT,2011					  flag_bits);2012	}2013}2014 2015/**2016 * ibmvscsis_mad() - Service a MAnagement Data gram.2017 * @vscsi:	Pointer to our adapter structure2018 * @crq:	Pointer to the CRQ entry containing the MAD request2019 *2020 * EXECUTION ENVIRONMENT:2021 *	Interrupt, called with adapter lock held2022 */2023static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq)2024{2025	struct iu_entry *iue;2026	struct ibmvscsis_cmd *cmd;2027	struct mad_common *mad;2028	long rc = ADAPT_SUCCESS;2029 2030	switch (vscsi->state) {2031		/*2032		 * We have not exchanged Init Msgs yet, so this MAD was sent2033		 * before the last Transport Event; client will not be2034		 * expecting a response.2035		 */2036	case WAIT_CONNECTION:2037		dev_dbg(&vscsi->dev, "mad: in Wait Connection state, ignoring MAD, flags %d\n",2038			vscsi->flags);2039		return ADAPT_SUCCESS;2040 2041	case SRP_PROCESSING:2042	case CONNECTED:2043		break;2044 2045		/*2046		 * We should never get here while we're in these states.2047		 * Just log an error and get out.2048		 */2049	case UNCONFIGURING:2050	case WAIT_IDLE:2051	case ERR_DISCONNECT:2052	case ERR_DISCONNECT_RECONNECT:2053	default:2054		dev_err(&vscsi->dev, "mad: invalid adapter state %d for mad\n",2055			vscsi->state);2056		return ADAPT_SUCCESS;2057	}2058 2059	cmd = ibmvscsis_get_free_cmd(vscsi);2060	if (!cmd) {2061		dev_err(&vscsi->dev, "mad: failed to get cmd, debit %d\n",2062			vscsi->debit);2063		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2064		return ERROR;2065	}2066	iue = cmd->iue;2067	cmd->type = ADAPTER_MAD;2068 2069	rc = ibmvscsis_copy_crq_packet(vscsi, cmd, crq);2070	if (!rc) {2071		mad = (struct mad_common *)&vio_iu(iue)->mad;2072 2073		dev_dbg(&vscsi->dev, "mad: type %d\n", be32_to_cpu(mad->type));2074 2075		rc = ibmvscsis_process_mad(vscsi, iue);2076 2077		dev_dbg(&vscsi->dev, "mad: status %hd, rc %ld\n",2078			be16_to_cpu(mad->status), rc);2079 2080		if (!rc)2081			ibmvscsis_send_mad_resp(vscsi, cmd, crq);2082	} else {2083		ibmvscsis_free_cmd_resources(vscsi, cmd);2084	}2085 2086	dev_dbg(&vscsi->dev, "Leaving mad, rc %ld\n", rc);2087	return rc;2088}2089 2090/**2091 * ibmvscsis_login_rsp() - Create/copy a login response notice to the client2092 * @vscsi:	Pointer to our adapter structure2093 * @cmd:	Pointer to the command for the SRP Login request2094 *2095 * EXECUTION ENVIRONMENT:2096 *	Interrupt, interrupt lock held2097 */2098static long ibmvscsis_login_rsp(struct scsi_info *vscsi,2099				struct ibmvscsis_cmd *cmd)2100{2101	struct iu_entry *iue = cmd->iue;2102	struct srp_login_rsp *rsp = &vio_iu(iue)->srp.login_rsp;2103	struct format_code *fmt;2104	uint flag_bits = 0;2105	long rc = ADAPT_SUCCESS;2106 2107	memset(rsp, 0, sizeof(struct srp_login_rsp));2108 2109	rsp->opcode = SRP_LOGIN_RSP;2110	rsp->req_lim_delta = cpu_to_be32(vscsi->request_limit);2111	rsp->tag = cmd->rsp.tag;2112	rsp->max_it_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);2113	rsp->max_ti_iu_len = cpu_to_be32(SRP_MAX_IU_LEN);2114	fmt = (struct format_code *)&rsp->buf_fmt;2115	fmt->buffers = SUPPORTED_FORMATS;2116	vscsi->credit = 0;2117 2118	cmd->rsp.len = sizeof(struct srp_login_rsp);2119 2120	dma_wmb();2121	rc = h_copy_rdma(cmd->rsp.len, vscsi->dds.window[LOCAL].liobn,2122			 iue->sbuf->dma, vscsi->dds.window[REMOTE].liobn,2123			 be64_to_cpu(iue->remote_token));2124 2125	switch (rc) {2126	case H_SUCCESS:2127		break;2128 2129	case H_PERMISSION:2130		if (connection_broken(vscsi))2131			flag_bits = RESPONSE_Q_DOWN | CLIENT_FAILED;2132		dev_err(&vscsi->dev, "login_rsp: error copying to client, rc %ld\n",2133			rc);2134		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT,2135					  flag_bits);2136		break;2137	case H_SOURCE_PARM:2138	case H_DEST_PARM:2139	default:2140		dev_err(&vscsi->dev, "login_rsp: error copying to client, rc %ld\n",2141			rc);2142		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2143		break;2144	}2145 2146	return rc;2147}2148 2149/**2150 * ibmvscsis_srp_login_rej() - Create/copy a login rejection notice to client2151 * @vscsi:	Pointer to our adapter structure2152 * @cmd:	Pointer to the command for the SRP Login request2153 * @reason:	The reason the SRP Login is being rejected, per SRP protocol2154 *2155 * EXECUTION ENVIRONMENT:2156 *	Interrupt, interrupt lock held2157 */2158static long ibmvscsis_srp_login_rej(struct scsi_info *vscsi,2159				    struct ibmvscsis_cmd *cmd, u32 reason)2160{2161	struct iu_entry *iue = cmd->iue;2162	struct srp_login_rej *rej = &vio_iu(iue)->srp.login_rej;2163	struct format_code *fmt;2164	uint flag_bits = 0;2165	long rc = ADAPT_SUCCESS;2166 2167	memset(rej, 0, sizeof(*rej));2168 2169	rej->opcode = SRP_LOGIN_REJ;2170	rej->reason = cpu_to_be32(reason);2171	rej->tag = cmd->rsp.tag;2172	fmt = (struct format_code *)&rej->buf_fmt;2173	fmt->buffers = SUPPORTED_FORMATS;2174 2175	cmd->rsp.len = sizeof(*rej);2176 2177	dma_wmb();2178	rc = h_copy_rdma(cmd->rsp.len, vscsi->dds.window[LOCAL].liobn,2179			 iue->sbuf->dma, vscsi->dds.window[REMOTE].liobn,2180			 be64_to_cpu(iue->remote_token));2181 2182	switch (rc) {2183	case H_SUCCESS:2184		break;2185	case H_PERMISSION:2186		if (connection_broken(vscsi))2187			flag_bits = RESPONSE_Q_DOWN | CLIENT_FAILED;2188		dev_err(&vscsi->dev, "login_rej: error copying to client, rc %ld\n",2189			rc);2190		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT,2191					  flag_bits);2192		break;2193	case H_SOURCE_PARM:2194	case H_DEST_PARM:2195	default:2196		dev_err(&vscsi->dev, "login_rej: error copying to client, rc %ld\n",2197			rc);2198		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2199		break;2200	}2201 2202	return rc;2203}2204 2205static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)2206{2207	char *name = tport->tport_name;2208	struct ibmvscsis_nexus *nexus;2209	struct scsi_info *vscsi = container_of(tport, struct scsi_info, tport);2210	int rc;2211 2212	if (tport->ibmv_nexus) {2213		dev_dbg(&vscsi->dev, "tport->ibmv_nexus already exists\n");2214		return 0;2215	}2216 2217	nexus = kzalloc(sizeof(*nexus), GFP_KERNEL);2218	if (!nexus) {2219		dev_err(&vscsi->dev, "Unable to allocate struct ibmvscsis_nexus\n");2220		return -ENOMEM;2221	}2222 2223	nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,2224					      TARGET_PROT_NORMAL, name, nexus,2225					      NULL);2226	if (IS_ERR(nexus->se_sess)) {2227		rc = PTR_ERR(nexus->se_sess);2228		goto transport_init_fail;2229	}2230 2231	tport->ibmv_nexus = nexus;2232 2233	return 0;2234 2235transport_init_fail:2236	kfree(nexus);2237	return rc;2238}2239 2240static int ibmvscsis_drop_nexus(struct ibmvscsis_tport *tport)2241{2242	struct se_session *se_sess;2243	struct ibmvscsis_nexus *nexus;2244 2245	nexus = tport->ibmv_nexus;2246	if (!nexus)2247		return -ENODEV;2248 2249	se_sess = nexus->se_sess;2250	if (!se_sess)2251		return -ENODEV;2252 2253	/*2254	 * Release the SCSI I_T Nexus to the emulated ibmvscsis Target Port2255	 */2256	target_remove_session(se_sess);2257	tport->ibmv_nexus = NULL;2258	kfree(nexus);2259 2260	return 0;2261}2262 2263/**2264 * ibmvscsis_srp_login() - Process an SRP Login Request2265 * @vscsi:	Pointer to our adapter structure2266 * @cmd:	Command element to use to process the SRP Login request2267 * @crq:	Pointer to CRQ entry containing the SRP Login request2268 *2269 * EXECUTION ENVIRONMENT:2270 *	Interrupt, called with interrupt lock held2271 */2272static long ibmvscsis_srp_login(struct scsi_info *vscsi,2273				struct ibmvscsis_cmd *cmd,2274				struct viosrp_crq *crq)2275{2276	struct iu_entry *iue = cmd->iue;2277	struct srp_login_req *req = &vio_iu(iue)->srp.login_req;2278	struct port_id {2279		__be64 id_extension;2280		__be64 io_guid;2281	} *iport, *tport;2282	struct format_code *fmt;2283	u32 reason = 0x0;2284	long rc = ADAPT_SUCCESS;2285 2286	iport = (struct port_id *)req->initiator_port_id;2287	tport = (struct port_id *)req->target_port_id;2288	fmt = (struct format_code *)&req->req_buf_fmt;2289	if (be32_to_cpu(req->req_it_iu_len) > SRP_MAX_IU_LEN)2290		reason = SRP_LOGIN_REJ_REQ_IT_IU_LENGTH_TOO_LARGE;2291	else if (be32_to_cpu(req->req_it_iu_len) < 64)2292		reason = SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL;2293	else if ((be64_to_cpu(iport->id_extension) > (MAX_NUM_PORTS - 1)) ||2294		 (be64_to_cpu(tport->id_extension) > (MAX_NUM_PORTS - 1)))2295		reason = SRP_LOGIN_REJ_UNABLE_ASSOCIATE_CHANNEL;2296	else if (req->req_flags & SRP_MULTICHAN_MULTI)2297		reason = SRP_LOGIN_REJ_MULTI_CHANNEL_UNSUPPORTED;2298	else if (fmt->buffers & (~SUPPORTED_FORMATS))2299		reason = SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT;2300	else if ((fmt->buffers & SUPPORTED_FORMATS) == 0)2301		reason = SRP_LOGIN_REJ_UNSUPPORTED_DESCRIPTOR_FMT;2302 2303	if (vscsi->state == SRP_PROCESSING)2304		reason = SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED;2305 2306	rc = ibmvscsis_make_nexus(&vscsi->tport);2307	if (rc)2308		reason = SRP_LOGIN_REJ_UNABLE_ESTABLISH_CHANNEL;2309 2310	cmd->rsp.format = VIOSRP_SRP_FORMAT;2311	cmd->rsp.tag = req->tag;2312 2313	dev_dbg(&vscsi->dev, "srp_login: reason 0x%x\n", reason);2314 2315	if (reason)2316		rc = ibmvscsis_srp_login_rej(vscsi, cmd, reason);2317	else2318		rc = ibmvscsis_login_rsp(vscsi, cmd);2319 2320	if (!rc) {2321		if (!reason)2322			vscsi->state = SRP_PROCESSING;2323 2324		list_add_tail(&cmd->list, &vscsi->waiting_rsp);2325		ibmvscsis_send_messages(vscsi);2326	} else {2327		ibmvscsis_free_cmd_resources(vscsi, cmd);2328	}2329 2330	dev_dbg(&vscsi->dev, "Leaving srp_login, rc %ld\n", rc);2331	return rc;2332}2333 2334/**2335 * ibmvscsis_srp_i_logout() - Helper Function to close I_T Nexus2336 * @vscsi:	Pointer to our adapter structure2337 * @cmd:	Command element to use to process the Implicit Logout request2338 * @crq:	Pointer to CRQ entry containing the Implicit Logout request2339 *2340 * Do the logic to close the I_T nexus.  This function may not2341 * behave to specification.2342 *2343 * EXECUTION ENVIRONMENT:2344 *	Interrupt, interrupt lock held2345 */2346static long ibmvscsis_srp_i_logout(struct scsi_info *vscsi,2347				   struct ibmvscsis_cmd *cmd,2348				   struct viosrp_crq *crq)2349{2350	struct iu_entry *iue = cmd->iue;2351	struct srp_i_logout *log_out = &vio_iu(iue)->srp.i_logout;2352 2353	if ((vscsi->debit > 0) || !list_empty(&vscsi->schedule_q) ||2354	    !list_empty(&vscsi->waiting_rsp)) {2355		dev_err(&vscsi->dev, "i_logout: outstanding work\n");2356		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);2357	} else {2358		cmd->rsp.format = SRP_FORMAT;2359		cmd->rsp.tag = log_out->tag;2360		cmd->rsp.len = sizeof(struct mad_common);2361		list_add_tail(&cmd->list, &vscsi->waiting_rsp);2362		ibmvscsis_send_messages(vscsi);2363 2364		ibmvscsis_post_disconnect(vscsi, WAIT_IDLE, 0);2365	}2366 2367	return ADAPT_SUCCESS;2368}2369 2370/* Called with intr lock held */2371static void ibmvscsis_srp_cmd(struct scsi_info *vscsi, struct viosrp_crq *crq)2372{2373	struct ibmvscsis_cmd *cmd;2374	struct iu_entry *iue;2375	struct srp_cmd *srp;2376	struct srp_tsk_mgmt *tsk;2377	long rc;2378 2379	if (vscsi->request_limit - vscsi->debit <= 0) {2380		/* Client has exceeded request limit */2381		dev_err(&vscsi->dev, "Client exceeded the request limit (%d), debit %d\n",2382			vscsi->request_limit, vscsi->debit);2383		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2384		return;2385	}2386 2387	cmd = ibmvscsis_get_free_cmd(vscsi);2388	if (!cmd) {2389		dev_err(&vscsi->dev, "srp_cmd failed to get cmd, debit %d\n",2390			vscsi->debit);2391		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2392		return;2393	}2394	iue = cmd->iue;2395	srp = &vio_iu(iue)->srp.cmd;2396 2397	rc = ibmvscsis_copy_crq_packet(vscsi, cmd, crq);2398	if (rc) {2399		ibmvscsis_free_cmd_resources(vscsi, cmd);2400		return;2401	}2402 2403	if (vscsi->state == SRP_PROCESSING) {2404		switch (srp->opcode) {2405		case SRP_LOGIN_REQ:2406			rc = ibmvscsis_srp_login(vscsi, cmd, crq);2407			break;2408 2409		case SRP_TSK_MGMT:2410			tsk = &vio_iu(iue)->srp.tsk_mgmt;2411			dev_dbg(&vscsi->dev, "tsk_mgmt tag: %llu (0x%llx)\n",2412				tsk->tag, tsk->tag);2413			cmd->rsp.tag = tsk->tag;2414			vscsi->debit += 1;2415			cmd->type = TASK_MANAGEMENT;2416			list_add_tail(&cmd->list, &vscsi->schedule_q);2417			queue_work(vscsi->work_q, &cmd->work);2418			break;2419 2420		case SRP_CMD:2421			dev_dbg(&vscsi->dev, "srp_cmd tag: %llu (0x%llx)\n",2422				srp->tag, srp->tag);2423			cmd->rsp.tag = srp->tag;2424			vscsi->debit += 1;2425			cmd->type = SCSI_CDB;2426			/*2427			 * We want to keep track of work waiting for2428			 * the workqueue.2429			 */2430			list_add_tail(&cmd->list, &vscsi->schedule_q);2431			queue_work(vscsi->work_q, &cmd->work);2432			break;2433 2434		case SRP_I_LOGOUT:2435			rc = ibmvscsis_srp_i_logout(vscsi, cmd, crq);2436			break;2437 2438		case SRP_CRED_RSP:2439		case SRP_AER_RSP:2440		default:2441			ibmvscsis_free_cmd_resources(vscsi, cmd);2442			dev_err(&vscsi->dev, "invalid srp cmd, opcode %d\n",2443				(uint)srp->opcode);2444			ibmvscsis_post_disconnect(vscsi,2445						  ERR_DISCONNECT_RECONNECT, 0);2446			break;2447		}2448	} else if (srp->opcode == SRP_LOGIN_REQ && vscsi->state == CONNECTED) {2449		rc = ibmvscsis_srp_login(vscsi, cmd, crq);2450	} else {2451		ibmvscsis_free_cmd_resources(vscsi, cmd);2452		dev_err(&vscsi->dev, "Invalid state %d to handle srp cmd\n",2453			vscsi->state);2454		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2455	}2456}2457 2458/**2459 * ibmvscsis_ping_response() - Respond to a ping request2460 * @vscsi:	Pointer to our adapter structure2461 *2462 * Let the client know that the server is alive and waiting on2463 * its native I/O stack.2464 * If any type of error occurs from the call to queue a ping2465 * response then the client is either not accepting or receiving2466 * interrupts.  Disconnect with an error.2467 *2468 * EXECUTION ENVIRONMENT:2469 *	Interrupt, interrupt lock held2470 */2471static long ibmvscsis_ping_response(struct scsi_info *vscsi)2472{2473	struct viosrp_crq *crq;2474	u64 buffer[2] = { 0, 0 };2475	long rc;2476 2477	crq = (struct viosrp_crq *)&buffer;2478	crq->valid = VALID_CMD_RESP_EL;2479	crq->format = (u8)MESSAGE_IN_CRQ;2480	crq->status = PING_RESPONSE;2481 2482	rc = h_send_crq(vscsi->dds.unit_id, cpu_to_be64(buffer[MSG_HI]),2483			cpu_to_be64(buffer[MSG_LOW]));2484 2485	switch (rc) {2486	case H_SUCCESS:2487		break;2488	case H_CLOSED:2489		vscsi->flags |= CLIENT_FAILED;2490		fallthrough;2491	case H_DROPPED:2492		vscsi->flags |= RESPONSE_Q_DOWN;2493		fallthrough;2494	case H_REMOTE_PARM:2495		dev_err(&vscsi->dev, "ping_response: h_send_crq failed, rc %ld\n",2496			rc);2497		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2498		break;2499	default:2500		dev_err(&vscsi->dev, "ping_response: h_send_crq returned unknown rc %ld\n",2501			rc);2502		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);2503		break;2504	}2505 2506	return rc;2507}2508 2509/**2510 * ibmvscsis_parse_command() - Parse an element taken from the cmd rsp queue.2511 * @vscsi:	Pointer to our adapter structure2512 * @crq:	Pointer to CRQ element containing the SRP request2513 *2514 * This function will return success if the command queue element is valid2515 * and the srp iu or MAD request it pointed to was also valid.  That does2516 * not mean that an error was not returned to the client.2517 *2518 * EXECUTION ENVIRONMENT:2519 *	Interrupt, intr lock held2520 */2521static long ibmvscsis_parse_command(struct scsi_info *vscsi,2522				    struct viosrp_crq *crq)2523{2524	long rc = ADAPT_SUCCESS;2525 2526	switch (crq->valid) {2527	case VALID_CMD_RESP_EL:2528		switch (crq->format) {2529		case OS400_FORMAT:2530		case AIX_FORMAT:2531		case LINUX_FORMAT:2532		case MAD_FORMAT:2533			if (vscsi->flags & PROCESSING_MAD) {2534				rc = ERROR;2535				dev_err(&vscsi->dev, "parse_command: already processing mad\n");2536				ibmvscsis_post_disconnect(vscsi,2537						       ERR_DISCONNECT_RECONNECT,2538						       0);2539			} else {2540				vscsi->flags |= PROCESSING_MAD;2541				rc = ibmvscsis_mad(vscsi, crq);2542			}2543			break;2544 2545		case SRP_FORMAT:2546			ibmvscsis_srp_cmd(vscsi, crq);2547			break;2548 2549		case MESSAGE_IN_CRQ:2550			if (crq->status == PING)2551				ibmvscsis_ping_response(vscsi);2552			break;2553 2554		default:2555			dev_err(&vscsi->dev, "parse_command: invalid format %d\n",2556				(uint)crq->format);2557			ibmvscsis_post_disconnect(vscsi,2558						  ERR_DISCONNECT_RECONNECT, 0);2559			break;2560		}2561		break;2562 2563	case VALID_TRANS_EVENT:2564		rc = ibmvscsis_trans_event(vscsi, crq);2565		break;2566 2567	case VALID_INIT_MSG:2568		rc = ibmvscsis_init_msg(vscsi, crq);2569		break;2570 2571	default:2572		dev_err(&vscsi->dev, "parse_command: invalid valid field %d\n",2573			(uint)crq->valid);2574		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2575		break;2576	}2577 2578	/*2579	 * Return only what the interrupt handler cares2580	 * about. Most errors we keep right on trucking.2581	 */2582	rc = vscsi->flags & SCHEDULE_DISCONNECT;2583 2584	return rc;2585}2586 2587static int read_dma_window(struct scsi_info *vscsi)2588{2589	struct vio_dev *vdev = vscsi->dma_dev;2590	const __be32 *dma_window;2591	const __be32 *prop;2592 2593	/* TODO Using of_parse_dma_window would be better, but it doesn't give2594	 * a way to read multiple windows without already knowing the size of2595	 * a window or the number of windows.2596	 */2597	dma_window = (const __be32 *)vio_get_attribute(vdev,2598						       "ibm,my-dma-window",2599						       NULL);2600	if (!dma_window) {2601		dev_err(&vscsi->dev, "Couldn't find ibm,my-dma-window property\n");2602		return -1;2603	}2604 2605	vscsi->dds.window[LOCAL].liobn = be32_to_cpu(*dma_window);2606	dma_window++;2607 2608	prop = (const __be32 *)vio_get_attribute(vdev, "ibm,#dma-address-cells",2609						 NULL);2610	if (!prop) {2611		dev_warn(&vscsi->dev, "Couldn't find ibm,#dma-address-cells property\n");2612		dma_window++;2613	} else {2614		dma_window += be32_to_cpu(*prop);2615	}2616 2617	prop = (const __be32 *)vio_get_attribute(vdev, "ibm,#dma-size-cells",2618						 NULL);2619	if (!prop) {2620		dev_warn(&vscsi->dev, "Couldn't find ibm,#dma-size-cells property\n");2621		dma_window++;2622	} else {2623		dma_window += be32_to_cpu(*prop);2624	}2625 2626	/* dma_window should point to the second window now */2627	vscsi->dds.window[REMOTE].liobn = be32_to_cpu(*dma_window);2628 2629	return 0;2630}2631 2632static struct ibmvscsis_tport *ibmvscsis_lookup_port(const char *name)2633{2634	struct ibmvscsis_tport *tport = NULL;2635	struct vio_dev *vdev;2636	struct scsi_info *vscsi;2637 2638	spin_lock_bh(&ibmvscsis_dev_lock);2639	list_for_each_entry(vscsi, &ibmvscsis_dev_list, list) {2640		vdev = vscsi->dma_dev;2641		if (!strcmp(dev_name(&vdev->dev), name)) {2642			tport = &vscsi->tport;2643			break;2644		}2645	}2646	spin_unlock_bh(&ibmvscsis_dev_lock);2647 2648	return tport;2649}2650 2651/**2652 * ibmvscsis_parse_cmd() - Parse SRP Command2653 * @vscsi:	Pointer to our adapter structure2654 * @cmd:	Pointer to command element with SRP command2655 *2656 * Parse the srp command; if it is valid then submit it to tcm.2657 * Note: The return code does not reflect the status of the SCSI CDB.2658 *2659 * EXECUTION ENVIRONMENT:2660 *	Process level2661 */2662static void ibmvscsis_parse_cmd(struct scsi_info *vscsi,2663				struct ibmvscsis_cmd *cmd)2664{2665	struct iu_entry *iue = cmd->iue;2666	struct srp_cmd *srp = (struct srp_cmd *)iue->sbuf->buf;2667	struct ibmvscsis_nexus *nexus;2668	u64 data_len = 0;2669	enum dma_data_direction dir;2670	int attr = 0;2671 2672	nexus = vscsi->tport.ibmv_nexus;2673	/*2674	 * additional length in bytes.  Note that the SRP spec says that2675	 * additional length is in 4-byte words, but technically the2676	 * additional length field is only the upper 6 bits of the byte.2677	 * The lower 2 bits are reserved.  If the lower 2 bits are 0 (as2678	 * all reserved fields should be), then interpreting the byte as2679	 * an int will yield the length in bytes.2680	 */2681	if (srp->add_cdb_len & 0x03) {2682		dev_err(&vscsi->dev, "parse_cmd: reserved bits set in IU\n");2683		spin_lock_bh(&vscsi->intr_lock);2684		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2685		ibmvscsis_free_cmd_resources(vscsi, cmd);2686		spin_unlock_bh(&vscsi->intr_lock);2687		return;2688	}2689 2690	if (srp_get_desc_table(srp, &dir, &data_len)) {2691		dev_err(&vscsi->dev, "0x%llx: parsing SRP descriptor table failed.\n",2692			srp->tag);2693		goto fail;2694	}2695 2696	cmd->rsp.sol_not = srp->sol_not;2697 2698	switch (srp->task_attr) {2699	case SRP_SIMPLE_TASK:2700		attr = TCM_SIMPLE_TAG;2701		break;2702	case SRP_ORDERED_TASK:2703		attr = TCM_ORDERED_TAG;2704		break;2705	case SRP_HEAD_TASK:2706		attr = TCM_HEAD_TAG;2707		break;2708	case SRP_ACA_TASK:2709		attr = TCM_ACA_TAG;2710		break;2711	default:2712		dev_err(&vscsi->dev, "Invalid task attribute %d\n",2713			srp->task_attr);2714		goto fail;2715	}2716 2717	cmd->se_cmd.tag = be64_to_cpu(srp->tag);2718 2719	spin_lock_bh(&vscsi->intr_lock);2720	list_add_tail(&cmd->list, &vscsi->active_q);2721	spin_unlock_bh(&vscsi->intr_lock);2722 2723	srp->lun.scsi_lun[0] &= 0x3f;2724 2725	target_submit_cmd(&cmd->se_cmd, nexus->se_sess, srp->cdb,2726			  cmd->sense_buf, scsilun_to_int(&srp->lun),2727			  data_len, attr, dir, 0);2728	return;2729 2730fail:2731	spin_lock_bh(&vscsi->intr_lock);2732	ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT_RECONNECT, 0);2733	spin_unlock_bh(&vscsi->intr_lock);2734}2735 2736/**2737 * ibmvscsis_parse_task() - Parse SRP Task Management Request2738 * @vscsi:	Pointer to our adapter structure2739 * @cmd:	Pointer to command element with SRP task management request2740 *2741 * Parse the srp task management request; if it is valid then submit it to tcm.2742 * Note: The return code does not reflect the status of the task management2743 * request.2744 *2745 * EXECUTION ENVIRONMENT:2746 *	Processor level2747 */2748static void ibmvscsis_parse_task(struct scsi_info *vscsi,2749				 struct ibmvscsis_cmd *cmd)2750{2751	struct iu_entry *iue = cmd->iue;2752	struct srp_tsk_mgmt *srp_tsk = &vio_iu(iue)->srp.tsk_mgmt;2753	int tcm_type;2754	u64 tag_to_abort = 0;2755	int rc = 0;2756	struct ibmvscsis_nexus *nexus;2757 2758	nexus = vscsi->tport.ibmv_nexus;2759 2760	cmd->rsp.sol_not = srp_tsk->sol_not;2761 2762	switch (srp_tsk->tsk_mgmt_func) {2763	case SRP_TSK_ABORT_TASK:2764		tcm_type = TMR_ABORT_TASK;2765		tag_to_abort = be64_to_cpu(srp_tsk->task_tag);2766		break;2767	case SRP_TSK_ABORT_TASK_SET:2768		tcm_type = TMR_ABORT_TASK_SET;2769		break;2770	case SRP_TSK_CLEAR_TASK_SET:2771		tcm_type = TMR_CLEAR_TASK_SET;2772		break;2773	case SRP_TSK_LUN_RESET:2774		tcm_type = TMR_LUN_RESET;2775		break;2776	case SRP_TSK_CLEAR_ACA:2777		tcm_type = TMR_CLEAR_ACA;2778		break;2779	default:2780		dev_err(&vscsi->dev, "unknown task mgmt func %d\n",2781			srp_tsk->tsk_mgmt_func);2782		cmd->se_cmd.se_tmr_req->response =2783			TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;2784		rc = -1;2785		break;2786	}2787 2788	if (!rc) {2789		cmd->se_cmd.tag = be64_to_cpu(srp_tsk->tag);2790 2791		spin_lock_bh(&vscsi->intr_lock);2792		list_add_tail(&cmd->list, &vscsi->active_q);2793		spin_unlock_bh(&vscsi->intr_lock);2794 2795		srp_tsk->lun.scsi_lun[0] &= 0x3f;2796 2797		dev_dbg(&vscsi->dev, "calling submit_tmr, func %d\n",2798			srp_tsk->tsk_mgmt_func);2799		rc = target_submit_tmr(&cmd->se_cmd, nexus->se_sess, NULL,2800				       scsilun_to_int(&srp_tsk->lun), srp_tsk,2801				       tcm_type, GFP_KERNEL, tag_to_abort, 0);2802		if (rc) {2803			dev_err(&vscsi->dev, "target_submit_tmr failed, rc %d\n",2804				rc);2805			spin_lock_bh(&vscsi->intr_lock);2806			list_del(&cmd->list);2807			spin_unlock_bh(&vscsi->intr_lock);2808			cmd->se_cmd.se_tmr_req->response =2809				TMR_FUNCTION_REJECTED;2810		}2811	}2812 2813	if (rc)2814		transport_send_check_condition_and_sense(&cmd->se_cmd, 0, 0);2815}2816 2817static void ibmvscsis_scheduler(struct work_struct *work)2818{2819	struct ibmvscsis_cmd *cmd = container_of(work, struct ibmvscsis_cmd,2820						 work);2821	struct scsi_info *vscsi = cmd->adapter;2822 2823	spin_lock_bh(&vscsi->intr_lock);2824 2825	/* Remove from schedule_q */2826	list_del(&cmd->list);2827 2828	/* Don't submit cmd if we're disconnecting */2829	if (vscsi->flags & (SCHEDULE_DISCONNECT | DISCONNECT_SCHEDULED)) {2830		ibmvscsis_free_cmd_resources(vscsi, cmd);2831 2832		/* ibmvscsis_disconnect might be waiting for us */2833		if (list_empty(&vscsi->active_q) &&2834		    list_empty(&vscsi->schedule_q) &&2835		    (vscsi->flags & WAIT_FOR_IDLE)) {2836			vscsi->flags &= ~WAIT_FOR_IDLE;2837			complete(&vscsi->wait_idle);2838		}2839 2840		spin_unlock_bh(&vscsi->intr_lock);2841		return;2842	}2843 2844	spin_unlock_bh(&vscsi->intr_lock);2845 2846	switch (cmd->type) {2847	case SCSI_CDB:2848		ibmvscsis_parse_cmd(vscsi, cmd);2849		break;2850	case TASK_MANAGEMENT:2851		ibmvscsis_parse_task(vscsi, cmd);2852		break;2853	default:2854		dev_err(&vscsi->dev, "scheduler, invalid cmd type %d\n",2855			cmd->type);2856		spin_lock_bh(&vscsi->intr_lock);2857		ibmvscsis_free_cmd_resources(vscsi, cmd);2858		spin_unlock_bh(&vscsi->intr_lock);2859		break;2860	}2861}2862 2863static int ibmvscsis_alloc_cmds(struct scsi_info *vscsi, int num)2864{2865	struct ibmvscsis_cmd *cmd;2866	int i;2867 2868	INIT_LIST_HEAD(&vscsi->free_cmd);2869	vscsi->cmd_pool = kcalloc(num, sizeof(struct ibmvscsis_cmd),2870				  GFP_KERNEL);2871	if (!vscsi->cmd_pool)2872		return -ENOMEM;2873 2874	for (i = 0, cmd = (struct ibmvscsis_cmd *)vscsi->cmd_pool; i < num;2875	     i++, cmd++) {2876		cmd->abort_cmd = NULL;2877		cmd->adapter = vscsi;2878		INIT_WORK(&cmd->work, ibmvscsis_scheduler);2879		list_add_tail(&cmd->list, &vscsi->free_cmd);2880	}2881 2882	return 0;2883}2884 2885static void ibmvscsis_free_cmds(struct scsi_info *vscsi)2886{2887	kfree(vscsi->cmd_pool);2888	vscsi->cmd_pool = NULL;2889	INIT_LIST_HEAD(&vscsi->free_cmd);2890}2891 2892/**2893 * ibmvscsis_service_wait_q() - Service Waiting Queue2894 * @timer:	Pointer to timer which has expired2895 *2896 * This routine is called when the timer pops to service the waiting2897 * queue. Elements on the queue have completed, their responses have been2898 * copied to the client, but the client's response queue was full so2899 * the queue message could not be sent. The routine grabs the proper locks2900 * and calls send messages.2901 *2902 * EXECUTION ENVIRONMENT:2903 *	called at interrupt level2904 */2905static enum hrtimer_restart ibmvscsis_service_wait_q(struct hrtimer *timer)2906{2907	struct timer_cb *p_timer = container_of(timer, struct timer_cb, timer);2908	struct scsi_info *vscsi = container_of(p_timer, struct scsi_info,2909					       rsp_q_timer);2910 2911	spin_lock_bh(&vscsi->intr_lock);2912	p_timer->timer_pops += 1;2913	p_timer->started = false;2914	ibmvscsis_send_messages(vscsi);2915	spin_unlock_bh(&vscsi->intr_lock);2916 2917	return HRTIMER_NORESTART;2918}2919 2920static long ibmvscsis_alloctimer(struct scsi_info *vscsi)2921{2922	struct timer_cb *p_timer;2923 2924	p_timer = &vscsi->rsp_q_timer;2925	hrtimer_init(&p_timer->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);2926 2927	p_timer->timer.function = ibmvscsis_service_wait_q;2928	p_timer->started = false;2929	p_timer->timer_pops = 0;2930 2931	return ADAPT_SUCCESS;2932}2933 2934static void ibmvscsis_freetimer(struct scsi_info *vscsi)2935{2936	struct timer_cb *p_timer;2937 2938	p_timer = &vscsi->rsp_q_timer;2939 2940	(void)hrtimer_cancel(&p_timer->timer);2941 2942	p_timer->started = false;2943	p_timer->timer_pops = 0;2944}2945 2946static irqreturn_t ibmvscsis_interrupt(int dummy, void *data)2947{2948	struct scsi_info *vscsi = data;2949 2950	vio_disable_interrupts(vscsi->dma_dev);2951	tasklet_schedule(&vscsi->work_task);2952 2953	return IRQ_HANDLED;2954}2955 2956/**2957 * ibmvscsis_enable_change_state() - Set new state based on enabled status2958 * @vscsi:	Pointer to our adapter structure2959 *2960 * This function determines our new state now that we are enabled.  This2961 * may involve sending an Init Complete message to the client.2962 *2963 * Must be called with interrupt lock held.2964 */2965static long ibmvscsis_enable_change_state(struct scsi_info *vscsi)2966{2967	int bytes;2968	long rc = ADAPT_SUCCESS;2969 2970	bytes = vscsi->cmd_q.size * PAGE_SIZE;2971	rc = h_reg_crq(vscsi->dds.unit_id, vscsi->cmd_q.crq_token, bytes);2972	if (rc == H_CLOSED || rc == H_SUCCESS) {2973		vscsi->state = WAIT_CONNECTION;2974		rc = ibmvscsis_establish_new_q(vscsi);2975	}2976 2977	if (rc != ADAPT_SUCCESS) {2978		vscsi->state = ERR_DISCONNECTED;2979		vscsi->flags |= RESPONSE_Q_DOWN;2980	}2981 2982	return rc;2983}2984 2985/**2986 * ibmvscsis_create_command_q() - Create Command Queue2987 * @vscsi:	Pointer to our adapter structure2988 * @num_cmds:	Currently unused.  In the future, may be used to determine2989 *		the size of the CRQ.2990 *2991 * Allocates memory for command queue maps remote memory into an ioba2992 * initializes the command response queue2993 *2994 * EXECUTION ENVIRONMENT:2995 *	Process level only2996 */2997static long ibmvscsis_create_command_q(struct scsi_info *vscsi, int num_cmds)2998{2999	int pages;3000	struct vio_dev *vdev = vscsi->dma_dev;3001 3002	/* We might support multiple pages in the future, but just 1 for now */3003	pages = 1;3004 3005	vscsi->cmd_q.size = pages;3006 3007	vscsi->cmd_q.base_addr =3008		(struct viosrp_crq *)get_zeroed_page(GFP_KERNEL);3009	if (!vscsi->cmd_q.base_addr)3010		return -ENOMEM;3011 3012	vscsi->cmd_q.mask = ((uint)pages * CRQ_PER_PAGE) - 1;3013 3014	vscsi->cmd_q.crq_token = dma_map_single(&vdev->dev,3015						vscsi->cmd_q.base_addr,3016						PAGE_SIZE, DMA_BIDIRECTIONAL);3017	if (dma_mapping_error(&vdev->dev, vscsi->cmd_q.crq_token)) {3018		free_page((unsigned long)vscsi->cmd_q.base_addr);3019		return -ENOMEM;3020	}3021 3022	return 0;3023}3024 3025/**3026 * ibmvscsis_destroy_command_q - Destroy Command Queue3027 * @vscsi:	Pointer to our adapter structure3028 *3029 * Releases memory for command queue and unmaps mapped remote memory.3030 *3031 * EXECUTION ENVIRONMENT:3032 *	Process level only3033 */3034static void ibmvscsis_destroy_command_q(struct scsi_info *vscsi)3035{3036	dma_unmap_single(&vscsi->dma_dev->dev, vscsi->cmd_q.crq_token,3037			 PAGE_SIZE, DMA_BIDIRECTIONAL);3038	free_page((unsigned long)vscsi->cmd_q.base_addr);3039	vscsi->cmd_q.base_addr = NULL;3040	vscsi->state = NO_QUEUE;3041}3042 3043static u8 ibmvscsis_fast_fail(struct scsi_info *vscsi,3044			      struct ibmvscsis_cmd *cmd)3045{3046	struct iu_entry *iue = cmd->iue;3047	struct se_cmd *se_cmd = &cmd->se_cmd;3048	struct srp_cmd *srp = (struct srp_cmd *)iue->sbuf->buf;3049	struct scsi_sense_hdr sshdr;3050	u8 rc = se_cmd->scsi_status;3051 3052	if (vscsi->fast_fail && (READ_CMD(srp->cdb) || WRITE_CMD(srp->cdb)))3053		if (scsi_normalize_sense(se_cmd->sense_buffer,3054					 se_cmd->scsi_sense_length, &sshdr))3055			if (sshdr.sense_key == HARDWARE_ERROR &&3056			    (se_cmd->residual_count == 0 ||3057			     se_cmd->residual_count == se_cmd->data_length)) {3058				rc = NO_SENSE;3059				cmd->flags |= CMD_FAST_FAIL;3060			}3061 3062	return rc;3063}3064 3065/**3066 * srp_build_response() - Build an SRP response buffer3067 * @vscsi:	Pointer to our adapter structure3068 * @cmd:	Pointer to command for which to send the response3069 * @len_p:	Where to return the length of the IU response sent.  This3070 *		is needed to construct the CRQ response.3071 *3072 * Build the SRP response buffer and copy it to the client's memory space.3073 */3074static long srp_build_response(struct scsi_info *vscsi,3075			       struct ibmvscsis_cmd *cmd, uint *len_p)3076{3077	struct iu_entry *iue = cmd->iue;3078	struct se_cmd *se_cmd = &cmd->se_cmd;3079	struct srp_rsp *rsp;3080	uint len;3081	u32 rsp_code;3082	char *data;3083	u32 *tsk_status;3084	long rc = ADAPT_SUCCESS;3085 3086	spin_lock_bh(&vscsi->intr_lock);3087 3088	rsp = &vio_iu(iue)->srp.rsp;3089	len = sizeof(*rsp);3090	memset(rsp, 0, len);3091	data = rsp->data;3092 3093	rsp->opcode = SRP_RSP;3094 3095	rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit);3096	rsp->tag = cmd->rsp.tag;3097	rsp->flags = 0;3098 3099	if (cmd->type == SCSI_CDB) {3100		rsp->status = ibmvscsis_fast_fail(vscsi, cmd);3101		if (rsp->status) {3102			dev_dbg(&vscsi->dev, "build_resp: cmd %p, scsi status %d\n",3103				cmd, (int)rsp->status);3104			ibmvscsis_determine_resid(se_cmd, rsp);3105			if (se_cmd->scsi_sense_length && se_cmd->sense_buffer) {3106				rsp->sense_data_len =3107					cpu_to_be32(se_cmd->scsi_sense_length);3108				rsp->flags |= SRP_RSP_FLAG_SNSVALID;3109				len += se_cmd->scsi_sense_length;3110				memcpy(data, se_cmd->sense_buffer,3111				       se_cmd->scsi_sense_length);3112			}3113			rsp->sol_not = (cmd->rsp.sol_not & UCSOLNT) >>3114				UCSOLNT_RESP_SHIFT;3115		} else if (cmd->flags & CMD_FAST_FAIL) {3116			dev_dbg(&vscsi->dev, "build_resp: cmd %p, fast fail\n",3117				cmd);3118			rsp->sol_not = (cmd->rsp.sol_not & UCSOLNT) >>3119				UCSOLNT_RESP_SHIFT;3120		} else {3121			rsp->sol_not = (cmd->rsp.sol_not & SCSOLNT) >>3122				SCSOLNT_RESP_SHIFT;3123		}3124	} else {3125		/* this is task management */3126		rsp->status = 0;3127		rsp->resp_data_len = cpu_to_be32(4);3128		rsp->flags |= SRP_RSP_FLAG_RSPVALID;3129 3130		switch (se_cmd->se_tmr_req->response) {3131		case TMR_FUNCTION_COMPLETE:3132		case TMR_TASK_DOES_NOT_EXIST:3133			rsp_code = SRP_TASK_MANAGEMENT_FUNCTION_COMPLETE;3134			rsp->sol_not = (cmd->rsp.sol_not & SCSOLNT) >>3135				SCSOLNT_RESP_SHIFT;3136			break;3137		case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED:3138		case TMR_LUN_DOES_NOT_EXIST:3139			rsp_code = SRP_TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED;3140			rsp->sol_not = (cmd->rsp.sol_not & UCSOLNT) >>3141				UCSOLNT_RESP_SHIFT;3142			break;3143		case TMR_FUNCTION_FAILED:3144		case TMR_FUNCTION_REJECTED:3145		default:3146			rsp_code = SRP_TASK_MANAGEMENT_FUNCTION_FAILED;3147			rsp->sol_not = (cmd->rsp.sol_not & UCSOLNT) >>3148				UCSOLNT_RESP_SHIFT;3149			break;3150		}3151 3152		tsk_status = (u32 *)data;3153		*tsk_status = cpu_to_be32(rsp_code);3154		data = (char *)(tsk_status + 1);3155		len += 4;3156	}3157 3158	dma_wmb();3159	rc = h_copy_rdma(len, vscsi->dds.window[LOCAL].liobn, iue->sbuf->dma,3160			 vscsi->dds.window[REMOTE].liobn,3161			 be64_to_cpu(iue->remote_token));3162 3163	switch (rc) {3164	case H_SUCCESS:3165		vscsi->credit = 0;3166		*len_p = len;3167		break;3168	case H_PERMISSION:3169		if (connection_broken(vscsi))3170			vscsi->flags |= RESPONSE_Q_DOWN | CLIENT_FAILED;3171 3172		dev_err(&vscsi->dev, "build_response: error copying to client, rc %ld, flags 0x%x, state 0x%hx\n",3173			rc, vscsi->flags, vscsi->state);3174		break;3175	case H_SOURCE_PARM:3176	case H_DEST_PARM:3177	default:3178		dev_err(&vscsi->dev, "build_response: error copying to client, rc %ld\n",3179			rc);3180		break;3181	}3182 3183	spin_unlock_bh(&vscsi->intr_lock);3184 3185	return rc;3186}3187 3188static int ibmvscsis_rdma(struct ibmvscsis_cmd *cmd, struct scatterlist *sg,3189			  int nsg, struct srp_direct_buf *md, int nmd,3190			  enum dma_data_direction dir, unsigned int bytes)3191{3192	struct iu_entry *iue = cmd->iue;3193	struct srp_target *target = iue->target;3194	struct scsi_info *vscsi = target->ldata;3195	struct scatterlist *sgp;3196	dma_addr_t client_ioba, server_ioba;3197	ulong buf_len;3198	ulong client_len, server_len;3199	int md_idx;3200	long tx_len;3201	long rc = 0;3202 3203	if (bytes == 0)3204		return 0;3205 3206	sgp = sg;3207	client_len = 0;3208	server_len = 0;3209	md_idx = 0;3210	tx_len = bytes;3211 3212	do {3213		if (client_len == 0) {3214			if (md_idx >= nmd) {3215				dev_err(&vscsi->dev, "rdma: ran out of client memory descriptors\n");3216				rc = -EIO;3217				break;3218			}3219			client_ioba = be64_to_cpu(md[md_idx].va);3220			client_len = be32_to_cpu(md[md_idx].len);3221		}3222		if (server_len == 0) {3223			if (!sgp) {3224				dev_err(&vscsi->dev, "rdma: ran out of scatter/gather list\n");3225				rc = -EIO;3226				break;3227			}3228			server_ioba = sg_dma_address(sgp);3229			server_len = sg_dma_len(sgp);3230		}3231 3232		buf_len = tx_len;3233 3234		if (buf_len > client_len)3235			buf_len = client_len;3236 3237		if (buf_len > server_len)3238			buf_len = server_len;3239 3240		if (buf_len > max_vdma_size)3241			buf_len = max_vdma_size;3242 3243		if (dir == DMA_TO_DEVICE) {3244			/* read from client */3245			rc = h_copy_rdma(buf_len,3246					 vscsi->dds.window[REMOTE].liobn,3247					 client_ioba,3248					 vscsi->dds.window[LOCAL].liobn,3249					 server_ioba);3250		} else {3251			/* The h_copy_rdma will cause phyp, running in another3252			 * partition, to read memory, so we need to make sure3253			 * the data has been written out, hence these syncs.3254			 */3255			/* ensure that everything is in memory */3256			isync();3257			/* ensure that memory has been made visible */3258			dma_wmb();3259			rc = h_copy_rdma(buf_len,3260					 vscsi->dds.window[LOCAL].liobn,3261					 server_ioba,3262					 vscsi->dds.window[REMOTE].liobn,3263					 client_ioba);3264		}3265		switch (rc) {3266		case H_SUCCESS:3267			break;3268		case H_PERMISSION:3269		case H_SOURCE_PARM:3270		case H_DEST_PARM:3271			if (connection_broken(vscsi)) {3272				spin_lock_bh(&vscsi->intr_lock);3273				vscsi->flags |=3274					(RESPONSE_Q_DOWN | CLIENT_FAILED);3275				spin_unlock_bh(&vscsi->intr_lock);3276			}3277			dev_err(&vscsi->dev, "rdma: h_copy_rdma failed, rc %ld\n",3278				rc);3279			break;3280 3281		default:3282			dev_err(&vscsi->dev, "rdma: unknown error %ld from h_copy_rdma\n",3283				rc);3284			break;3285		}3286 3287		if (!rc) {3288			tx_len -= buf_len;3289			if (tx_len) {3290				client_len -= buf_len;3291				if (client_len == 0)3292					md_idx++;3293				else3294					client_ioba += buf_len;3295 3296				server_len -= buf_len;3297				if (server_len == 0)3298					sgp = sg_next(sgp);3299				else3300					server_ioba += buf_len;3301			} else {3302				break;3303			}3304		}3305	} while (!rc);3306 3307	return rc;3308}3309 3310/**3311 * ibmvscsis_handle_crq() - Handle CRQ3312 * @data:	Pointer to our adapter structure3313 *3314 * Read the command elements from the command queue and copy the payloads3315 * associated with the command elements to local memory and execute the3316 * SRP requests.3317 *3318 * Note: this is an edge triggered interrupt. It can not be shared.3319 */3320static void ibmvscsis_handle_crq(unsigned long data)3321{3322	struct scsi_info *vscsi = (struct scsi_info *)data;3323	struct viosrp_crq *crq;3324	long rc;3325	bool ack = true;3326	volatile u8 valid;3327 3328	spin_lock_bh(&vscsi->intr_lock);3329 3330	dev_dbg(&vscsi->dev, "got interrupt\n");3331 3332	/*3333	 * if we are in a path where we are waiting for all pending commands3334	 * to complete because we received a transport event and anything in3335	 * the command queue is for a new connection, do nothing3336	 */3337	if (TARGET_STOP(vscsi)) {3338		vio_enable_interrupts(vscsi->dma_dev);3339 3340		dev_dbg(&vscsi->dev, "handle_crq, don't process: flags 0x%x, state 0x%hx\n",3341			vscsi->flags, vscsi->state);3342		spin_unlock_bh(&vscsi->intr_lock);3343		return;3344	}3345 3346	rc = vscsi->flags & SCHEDULE_DISCONNECT;3347	crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;3348	valid = crq->valid;3349	dma_rmb();3350 3351	while (valid) {3352		/*3353		 * These are edege triggered interrupts. After dropping out of3354		 * the while loop, the code must check for work since an3355		 * interrupt could be lost, and an elment be left on the queue,3356		 * hence the label.3357		 */3358cmd_work:3359		vscsi->cmd_q.index =3360			(vscsi->cmd_q.index + 1) & vscsi->cmd_q.mask;3361 3362		if (!rc) {3363			rc = ibmvscsis_parse_command(vscsi, crq);3364		} else {3365			if ((uint)crq->valid == VALID_TRANS_EVENT) {3366				/*3367				 * must service the transport layer events even3368				 * in an error state, dont break out until all3369				 * the consecutive transport events have been3370				 * processed3371				 */3372				rc = ibmvscsis_trans_event(vscsi, crq);3373			} else if (vscsi->flags & TRANS_EVENT) {3374				/*3375				 * if a transport event has occurred leave3376				 * everything but transport events on the queue3377				 *3378				 * need to decrement the queue index so we can3379				 * look at the element again3380				 */3381				if (vscsi->cmd_q.index)3382					vscsi->cmd_q.index -= 1;3383				else3384					/*3385					 * index is at 0 it just wrapped.3386					 * have it index last element in q3387					 */3388					vscsi->cmd_q.index = vscsi->cmd_q.mask;3389				break;3390			}3391		}3392 3393		crq->valid = INVALIDATE_CMD_RESP_EL;3394 3395		crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;3396		valid = crq->valid;3397		dma_rmb();3398	}3399 3400	if (!rc) {3401		if (ack) {3402			vio_enable_interrupts(vscsi->dma_dev);3403			ack = false;3404			dev_dbg(&vscsi->dev, "handle_crq, reenabling interrupts\n");3405		}3406		valid = crq->valid;3407		dma_rmb();3408		if (valid)3409			goto cmd_work;3410	} else {3411		dev_dbg(&vscsi->dev, "handle_crq, error: flags 0x%x, state 0x%hx, crq index 0x%x\n",3412			vscsi->flags, vscsi->state, vscsi->cmd_q.index);3413	}3414 3415	dev_dbg(&vscsi->dev, "Leaving handle_crq: schedule_q empty %d, flags 0x%x, state 0x%hx\n",3416		(int)list_empty(&vscsi->schedule_q), vscsi->flags,3417		vscsi->state);3418 3419	spin_unlock_bh(&vscsi->intr_lock);3420}3421 3422static int ibmvscsis_probe(struct vio_dev *vdev,3423			   const struct vio_device_id *id)3424{3425	struct scsi_info *vscsi;3426	int rc = 0;3427	long hrc = 0;3428 3429	vscsi = kzalloc(sizeof(*vscsi), GFP_KERNEL);3430	if (!vscsi) {3431		rc = -ENOMEM;3432		dev_err(&vdev->dev, "probe: allocation of adapter failed\n");3433		return rc;3434	}3435 3436	vscsi->dma_dev = vdev;3437	vscsi->dev = vdev->dev;3438	INIT_LIST_HEAD(&vscsi->schedule_q);3439	INIT_LIST_HEAD(&vscsi->waiting_rsp);3440	INIT_LIST_HEAD(&vscsi->active_q);3441 3442	snprintf(vscsi->tport.tport_name, IBMVSCSIS_NAMELEN, "%s",3443		 dev_name(&vdev->dev));3444 3445	dev_dbg(&vscsi->dev, "probe tport_name: %s\n", vscsi->tport.tport_name);3446 3447	rc = read_dma_window(vscsi);3448	if (rc)3449		goto free_adapter;3450	dev_dbg(&vscsi->dev, "Probe: liobn 0x%x, riobn 0x%x\n",3451		vscsi->dds.window[LOCAL].liobn,3452		vscsi->dds.window[REMOTE].liobn);3453 3454	snprintf(vscsi->eye, sizeof(vscsi->eye), "VSCSI %s", vdev->name);3455 3456	vscsi->dds.unit_id = vdev->unit_address;3457	strscpy(vscsi->dds.partition_name, partition_name,3458		sizeof(vscsi->dds.partition_name));3459	vscsi->dds.partition_num = partition_number;3460 3461	spin_lock_bh(&ibmvscsis_dev_lock);3462	list_add_tail(&vscsi->list, &ibmvscsis_dev_list);3463	spin_unlock_bh(&ibmvscsis_dev_lock);3464 3465	/*3466	 * TBD: How do we determine # of cmds to request?  Do we know how3467	 * many "children" we have?3468	 */3469	vscsi->request_limit = INITIAL_SRP_LIMIT;3470	rc = srp_target_alloc(&vscsi->target, &vdev->dev, vscsi->request_limit,3471			      SRP_MAX_IU_LEN);3472	if (rc)3473		goto rem_list;3474 3475	vscsi->target.ldata = vscsi;3476 3477	rc = ibmvscsis_alloc_cmds(vscsi, vscsi->request_limit);3478	if (rc) {3479		dev_err(&vscsi->dev, "alloc_cmds failed, rc %d, num %d\n",3480			rc, vscsi->request_limit);3481		goto free_target;3482	}3483 3484	/*3485	 * Note: the lock is used in freeing timers, so must initialize3486	 * first so that ordering in case of error is correct.3487	 */3488	spin_lock_init(&vscsi->intr_lock);3489 3490	rc = ibmvscsis_alloctimer(vscsi);3491	if (rc) {3492		dev_err(&vscsi->dev, "probe: alloctimer failed, rc %d\n", rc);3493		goto free_cmds;3494	}3495 3496	rc = ibmvscsis_create_command_q(vscsi, 256);3497	if (rc) {3498		dev_err(&vscsi->dev, "probe: create_command_q failed, rc %d\n",3499			rc);3500		goto free_timer;3501	}3502 3503	vscsi->map_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);3504	if (!vscsi->map_buf) {3505		rc = -ENOMEM;3506		dev_err(&vscsi->dev, "probe: allocating cmd buffer failed\n");3507		goto destroy_queue;3508	}3509 3510	vscsi->map_ioba = dma_map_single(&vdev->dev, vscsi->map_buf, PAGE_SIZE,3511					 DMA_BIDIRECTIONAL);3512	if (dma_mapping_error(&vdev->dev, vscsi->map_ioba)) {3513		rc = -ENOMEM;3514		dev_err(&vscsi->dev, "probe: error mapping command buffer\n");3515		goto free_buf;3516	}3517 3518	hrc = h_vioctl(vscsi->dds.unit_id, H_GET_PARTNER_INFO,3519		       (u64)vscsi->map_ioba | ((u64)PAGE_SIZE << 32), 0, 0, 0,3520		       0);3521	if (hrc == H_SUCCESS)3522		vscsi->client_data.partition_number =3523			be64_to_cpu(*(u64 *)vscsi->map_buf);3524	/*3525	 * We expect the VIOCTL to fail if we're configured as "any3526	 * client can connect" and the client isn't activated yet.3527	 * We'll make the call again when he sends an init msg.3528	 */3529	dev_dbg(&vscsi->dev, "probe hrc %ld, client partition num %d\n",3530		hrc, vscsi->client_data.partition_number);3531 3532	tasklet_init(&vscsi->work_task, ibmvscsis_handle_crq,3533		     (unsigned long)vscsi);3534 3535	init_completion(&vscsi->wait_idle);3536	init_completion(&vscsi->unconfig);3537 3538	vscsi->work_q = alloc_workqueue("ibmvscsis%s", WQ_MEM_RECLAIM, 1,3539					dev_name(&vdev->dev));3540	if (!vscsi->work_q) {3541		rc = -ENOMEM;3542		dev_err(&vscsi->dev, "create_workqueue failed\n");3543		goto unmap_buf;3544	}3545 3546	rc = request_irq(vdev->irq, ibmvscsis_interrupt, 0, "ibmvscsis", vscsi);3547	if (rc) {3548		rc = -EPERM;3549		dev_err(&vscsi->dev, "probe: request_irq failed, rc %d\n", rc);3550		goto destroy_WQ;3551	}3552 3553	vscsi->state = WAIT_ENABLED;3554 3555	dev_set_drvdata(&vdev->dev, vscsi);3556 3557	return 0;3558 3559destroy_WQ:3560	destroy_workqueue(vscsi->work_q);3561unmap_buf:3562	dma_unmap_single(&vdev->dev, vscsi->map_ioba, PAGE_SIZE,3563			 DMA_BIDIRECTIONAL);3564free_buf:3565	kfree(vscsi->map_buf);3566destroy_queue:3567	tasklet_kill(&vscsi->work_task);3568	ibmvscsis_unregister_command_q(vscsi);3569	ibmvscsis_destroy_command_q(vscsi);3570free_timer:3571	ibmvscsis_freetimer(vscsi);3572free_cmds:3573	ibmvscsis_free_cmds(vscsi);3574free_target:3575	srp_target_free(&vscsi->target);3576rem_list:3577	spin_lock_bh(&ibmvscsis_dev_lock);3578	list_del(&vscsi->list);3579	spin_unlock_bh(&ibmvscsis_dev_lock);3580free_adapter:3581	kfree(vscsi);3582 3583	return rc;3584}3585 3586static void ibmvscsis_remove(struct vio_dev *vdev)3587{3588	struct scsi_info *vscsi = dev_get_drvdata(&vdev->dev);3589 3590	dev_dbg(&vscsi->dev, "remove (%s)\n", dev_name(&vscsi->dma_dev->dev));3591 3592	spin_lock_bh(&vscsi->intr_lock);3593	ibmvscsis_post_disconnect(vscsi, UNCONFIGURING, 0);3594	vscsi->flags |= CFG_SLEEPING;3595	spin_unlock_bh(&vscsi->intr_lock);3596	wait_for_completion(&vscsi->unconfig);3597 3598	vio_disable_interrupts(vdev);3599	free_irq(vdev->irq, vscsi);3600	destroy_workqueue(vscsi->work_q);3601	dma_unmap_single(&vdev->dev, vscsi->map_ioba, PAGE_SIZE,3602			 DMA_BIDIRECTIONAL);3603	kfree(vscsi->map_buf);3604	tasklet_kill(&vscsi->work_task);3605	ibmvscsis_destroy_command_q(vscsi);3606	ibmvscsis_freetimer(vscsi);3607	ibmvscsis_free_cmds(vscsi);3608	srp_target_free(&vscsi->target);3609	spin_lock_bh(&ibmvscsis_dev_lock);3610	list_del(&vscsi->list);3611	spin_unlock_bh(&ibmvscsis_dev_lock);3612	kfree(vscsi);3613}3614 3615static ssize_t partition_number_show(struct device *dev,3616				     struct device_attribute *attr, char *buf)3617{3618	return sysfs_emit(buf, "%x\n", partition_number);3619}3620 3621static ssize_t unit_address_show(struct device *dev,3622				 struct device_attribute *attr, char *buf)3623{3624	struct scsi_info *vscsi = container_of(dev, struct scsi_info, dev);3625 3626	return sysfs_emit(buf, "%x\n", vscsi->dma_dev->unit_address);3627}3628 3629static int ibmvscsis_get_system_info(void)3630{3631	struct device_node *rootdn, *vdevdn;3632	const char *id, *model, *name;3633	const uint *num;3634 3635	rootdn = of_find_node_by_path("/");3636	if (!rootdn)3637		return -ENOENT;3638 3639	model = of_get_property(rootdn, "model", NULL);3640	id = of_get_property(rootdn, "system-id", NULL);3641	if (model && id)3642		snprintf(system_id, sizeof(system_id), "%s-%s", model, id);3643 3644	name = of_get_property(rootdn, "ibm,partition-name", NULL);3645	if (name)3646		strscpy(partition_name, name, sizeof(partition_name));3647 3648	num = of_get_property(rootdn, "ibm,partition-no", NULL);3649	if (num)3650		partition_number = of_read_number(num, 1);3651 3652	of_node_put(rootdn);3653 3654	vdevdn = of_find_node_by_path("/vdevice");3655	if (vdevdn) {3656		const uint *mvds;3657 3658		mvds = of_get_property(vdevdn, "ibm,max-virtual-dma-size",3659				       NULL);3660		if (mvds)3661			max_vdma_size = *mvds;3662		of_node_put(vdevdn);3663	}3664 3665	return 0;3666}3667 3668static char *ibmvscsis_get_fabric_wwn(struct se_portal_group *se_tpg)3669{3670	struct ibmvscsis_tport *tport =3671		container_of(se_tpg, struct ibmvscsis_tport, se_tpg);3672 3673	return tport->tport_name;3674}3675 3676static u16 ibmvscsis_get_tag(struct se_portal_group *se_tpg)3677{3678	struct ibmvscsis_tport *tport =3679		container_of(se_tpg, struct ibmvscsis_tport, se_tpg);3680 3681	return tport->tport_tpgt;3682}3683 3684static u32 ibmvscsis_get_default_depth(struct se_portal_group *se_tpg)3685{3686	return 1;3687}3688 3689static int ibmvscsis_check_true(struct se_portal_group *se_tpg)3690{3691	return 1;3692}3693 3694static int ibmvscsis_check_stop_free(struct se_cmd *se_cmd)3695{3696	return target_put_sess_cmd(se_cmd);3697}3698 3699static void ibmvscsis_release_cmd(struct se_cmd *se_cmd)3700{3701	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,3702						 se_cmd);3703	struct scsi_info *vscsi = cmd->adapter;3704 3705	spin_lock_bh(&vscsi->intr_lock);3706	/* Remove from active_q */3707	list_move_tail(&cmd->list, &vscsi->waiting_rsp);3708	ibmvscsis_send_messages(vscsi);3709	spin_unlock_bh(&vscsi->intr_lock);3710}3711 3712static int ibmvscsis_write_pending(struct se_cmd *se_cmd)3713{3714	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,3715						 se_cmd);3716	struct scsi_info *vscsi = cmd->adapter;3717	struct iu_entry *iue = cmd->iue;3718	int rc;3719 3720	/*3721	 * If CLIENT_FAILED OR RESPONSE_Q_DOWN, then just return success3722	 * since LIO can't do anything about it, and we dont want to3723	 * attempt an srp_transfer_data.3724	 */3725	if ((vscsi->flags & (CLIENT_FAILED | RESPONSE_Q_DOWN))) {3726		dev_err(&vscsi->dev, "write_pending failed since: %d\n",3727			vscsi->flags);3728		return -EIO;3729 3730	}3731 3732	rc = srp_transfer_data(cmd, &vio_iu(iue)->srp.cmd, ibmvscsis_rdma,3733			       1, 1);3734	if (rc) {3735		dev_err(&vscsi->dev, "srp_transfer_data() failed: %d\n", rc);3736		return -EIO;3737	}3738	/*3739	 * We now tell TCM to add this WRITE CDB directly into the TCM storage3740	 * object execution queue.3741	 */3742	target_execute_cmd(se_cmd);3743	return 0;3744}3745 3746static int ibmvscsis_queue_data_in(struct se_cmd *se_cmd)3747{3748	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,3749						 se_cmd);3750	struct iu_entry *iue = cmd->iue;3751	struct scsi_info *vscsi = cmd->adapter;3752	uint len = 0;3753	int rc;3754 3755	rc = srp_transfer_data(cmd, &vio_iu(iue)->srp.cmd, ibmvscsis_rdma, 1,3756			       1);3757	if (rc) {3758		dev_err(&vscsi->dev, "srp_transfer_data failed: %d\n", rc);3759		se_cmd->scsi_sense_length = 18;3760		memset(se_cmd->sense_buffer, 0, se_cmd->scsi_sense_length);3761		/* Logical Unit Communication Time-out asc/ascq = 0x0801 */3762		scsi_build_sense_buffer(0, se_cmd->sense_buffer, MEDIUM_ERROR,3763					0x08, 0x01);3764	}3765 3766	srp_build_response(vscsi, cmd, &len);3767	cmd->rsp.format = SRP_FORMAT;3768	cmd->rsp.len = len;3769 3770	return 0;3771}3772 3773static int ibmvscsis_queue_status(struct se_cmd *se_cmd)3774{3775	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,3776						 se_cmd);3777	struct scsi_info *vscsi = cmd->adapter;3778	uint len;3779 3780	dev_dbg(&vscsi->dev, "queue_status %p\n", se_cmd);3781 3782	srp_build_response(vscsi, cmd, &len);3783	cmd->rsp.format = SRP_FORMAT;3784	cmd->rsp.len = len;3785 3786	return 0;3787}3788 3789static void ibmvscsis_queue_tm_rsp(struct se_cmd *se_cmd)3790{3791	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,3792						 se_cmd);3793	struct scsi_info *vscsi = cmd->adapter;3794	struct ibmvscsis_cmd *cmd_itr;3795	struct iu_entry *iue = iue = cmd->iue;3796	struct srp_tsk_mgmt *srp_tsk = &vio_iu(iue)->srp.tsk_mgmt;3797	u64 tag_to_abort = be64_to_cpu(srp_tsk->task_tag);3798	uint len;3799 3800	dev_dbg(&vscsi->dev, "queue_tm_rsp %p, status %d\n",3801		se_cmd, (int)se_cmd->se_tmr_req->response);3802 3803	if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK &&3804	    cmd->se_cmd.se_tmr_req->response == TMR_TASK_DOES_NOT_EXIST) {3805		spin_lock_bh(&vscsi->intr_lock);3806		list_for_each_entry(cmd_itr, &vscsi->active_q, list) {3807			if (tag_to_abort == cmd_itr->se_cmd.tag) {3808				cmd_itr->abort_cmd = cmd;3809				cmd->flags |= DELAY_SEND;3810				break;3811			}3812		}3813		spin_unlock_bh(&vscsi->intr_lock);3814	}3815 3816	srp_build_response(vscsi, cmd, &len);3817	cmd->rsp.format = SRP_FORMAT;3818	cmd->rsp.len = len;3819}3820 3821static void ibmvscsis_aborted_task(struct se_cmd *se_cmd)3822{3823	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,3824						 se_cmd);3825	struct scsi_info *vscsi = cmd->adapter;3826 3827	dev_dbg(&vscsi->dev, "ibmvscsis_aborted_task %p task_tag: %llu\n",3828		se_cmd, se_cmd->tag);3829}3830 3831static struct se_wwn *ibmvscsis_make_tport(struct target_fabric_configfs *tf,3832					   struct config_group *group,3833					   const char *name)3834{3835	struct ibmvscsis_tport *tport;3836	struct scsi_info *vscsi;3837 3838	tport = ibmvscsis_lookup_port(name);3839	if (tport) {3840		vscsi = container_of(tport, struct scsi_info, tport);3841		tport->tport_proto_id = SCSI_PROTOCOL_SRP;3842		dev_dbg(&vscsi->dev, "make_tport(%s), pointer:%p, tport_id:%x\n",3843			name, tport, tport->tport_proto_id);3844		return &tport->tport_wwn;3845	}3846 3847	return ERR_PTR(-EINVAL);3848}3849 3850static void ibmvscsis_drop_tport(struct se_wwn *wwn)3851{3852	struct ibmvscsis_tport *tport = container_of(wwn,3853						     struct ibmvscsis_tport,3854						     tport_wwn);3855	struct scsi_info *vscsi = container_of(tport, struct scsi_info, tport);3856 3857	dev_dbg(&vscsi->dev, "drop_tport(%s)\n",3858		config_item_name(&tport->tport_wwn.wwn_group.cg_item));3859}3860 3861static struct se_portal_group *ibmvscsis_make_tpg(struct se_wwn *wwn,3862						  const char *name)3863{3864	struct ibmvscsis_tport *tport =3865		container_of(wwn, struct ibmvscsis_tport, tport_wwn);3866	u16 tpgt;3867	int rc;3868 3869	if (strstr(name, "tpgt_") != name)3870		return ERR_PTR(-EINVAL);3871	rc = kstrtou16(name + 5, 0, &tpgt);3872	if (rc)3873		return ERR_PTR(rc);3874	tport->tport_tpgt = tpgt;3875 3876	tport->releasing = false;3877 3878	rc = core_tpg_register(&tport->tport_wwn, &tport->se_tpg,3879			       tport->tport_proto_id);3880	if (rc)3881		return ERR_PTR(rc);3882 3883	return &tport->se_tpg;3884}3885 3886static void ibmvscsis_drop_tpg(struct se_portal_group *se_tpg)3887{3888	struct ibmvscsis_tport *tport = container_of(se_tpg,3889						     struct ibmvscsis_tport,3890						     se_tpg);3891 3892	tport->releasing = true;3893	tport->enabled = false;3894 3895	/*3896	 * Release the virtual I_T Nexus for this ibmvscsis TPG3897	 */3898	ibmvscsis_drop_nexus(tport);3899	/*3900	 * Deregister the se_tpg from TCM..3901	 */3902	core_tpg_deregister(se_tpg);3903}3904 3905static ssize_t ibmvscsis_wwn_version_show(struct config_item *item,3906					  char *page)3907{3908	return scnprintf(page, PAGE_SIZE, "%s\n", IBMVSCSIS_VERSION);3909}3910CONFIGFS_ATTR_RO(ibmvscsis_wwn_, version);3911 3912static struct configfs_attribute *ibmvscsis_wwn_attrs[] = {3913	&ibmvscsis_wwn_attr_version,3914	NULL,3915};3916 3917 3918static int ibmvscsis_enable_tpg(struct se_portal_group *se_tpg, bool enable)3919{3920	struct ibmvscsis_tport *tport = container_of(se_tpg,3921						     struct ibmvscsis_tport,3922						     se_tpg);3923	struct scsi_info *vscsi = container_of(tport, struct scsi_info, tport);3924	long lrc;3925 3926	if (enable) {3927		spin_lock_bh(&vscsi->intr_lock);3928		tport->enabled = true;3929		lrc = ibmvscsis_enable_change_state(vscsi);3930		if (lrc)3931			dev_err(&vscsi->dev, "enable_change_state failed, rc %ld state %d\n",3932				lrc, vscsi->state);3933		spin_unlock_bh(&vscsi->intr_lock);3934	} else {3935		spin_lock_bh(&vscsi->intr_lock);3936		tport->enabled = false;3937		/* This simulates the server going down */3938		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT, 0);3939		spin_unlock_bh(&vscsi->intr_lock);3940	}3941 3942	return 0;3943}3944 3945static const struct target_core_fabric_ops ibmvscsis_ops = {3946	.module				= THIS_MODULE,3947	.fabric_name			= "ibmvscsis",3948	.max_data_sg_nents		= MAX_TXU / PAGE_SIZE,3949	.tpg_get_wwn			= ibmvscsis_get_fabric_wwn,3950	.tpg_get_tag			= ibmvscsis_get_tag,3951	.tpg_get_default_depth		= ibmvscsis_get_default_depth,3952	.tpg_check_demo_mode		= ibmvscsis_check_true,3953	.tpg_check_demo_mode_cache	= ibmvscsis_check_true,3954	.check_stop_free		= ibmvscsis_check_stop_free,3955	.release_cmd			= ibmvscsis_release_cmd,3956	.write_pending			= ibmvscsis_write_pending,3957	.queue_data_in			= ibmvscsis_queue_data_in,3958	.queue_status			= ibmvscsis_queue_status,3959	.queue_tm_rsp			= ibmvscsis_queue_tm_rsp,3960	.aborted_task			= ibmvscsis_aborted_task,3961	/*3962	 * Setup function pointers for logic in target_core_fabric_configfs.c3963	 */3964	.fabric_make_wwn		= ibmvscsis_make_tport,3965	.fabric_drop_wwn		= ibmvscsis_drop_tport,3966	.fabric_make_tpg		= ibmvscsis_make_tpg,3967	.fabric_enable_tpg		= ibmvscsis_enable_tpg,3968	.fabric_drop_tpg		= ibmvscsis_drop_tpg,3969 3970	.tfc_wwn_attrs			= ibmvscsis_wwn_attrs,3971 3972	.default_submit_type		= TARGET_DIRECT_SUBMIT,3973	.direct_submit_supp		= 1,3974};3975 3976static void ibmvscsis_dev_release(struct device *dev) {};3977 3978static DEVICE_STRING_ATTR_RO(system_id, S_IRUGO, system_id);3979 3980static struct device_attribute dev_attr_partition_number =3981	__ATTR(partition_number, S_IRUGO, partition_number_show, NULL);3982 3983static struct device_attribute dev_attr_unit_address =3984	__ATTR(unit_address, S_IRUGO, unit_address_show, NULL);3985 3986static struct attribute *ibmvscsis_dev_attrs[] = {3987	&dev_attr_system_id.attr.attr,3988	&dev_attr_partition_number.attr,3989	&dev_attr_unit_address.attr,3990};3991ATTRIBUTE_GROUPS(ibmvscsis_dev);3992 3993static struct class ibmvscsis_class = {3994	.name		= "ibmvscsis",3995	.dev_release	= ibmvscsis_dev_release,3996	.dev_groups	= ibmvscsis_dev_groups,3997};3998 3999static const struct vio_device_id ibmvscsis_device_table[] = {4000	{ "v-scsi-host", "IBM,v-scsi-host" },4001	{ "", "" }4002};4003MODULE_DEVICE_TABLE(vio, ibmvscsis_device_table);4004 4005static struct vio_driver ibmvscsis_driver = {4006	.name = "ibmvscsis",4007	.id_table = ibmvscsis_device_table,4008	.probe = ibmvscsis_probe,4009	.remove = ibmvscsis_remove,4010};4011 4012/*4013 * ibmvscsis_init() - Kernel Module initialization4014 *4015 * Note: vio_register_driver() registers callback functions, and at least one4016 * of those callback functions calls TCM - Linux IO Target Subsystem, thus4017 * the SCSI Target template must be registered before vio_register_driver()4018 * is called.4019 */4020static int __init ibmvscsis_init(void)4021{4022	int rc = 0;4023 4024	rc = ibmvscsis_get_system_info();4025	if (rc) {4026		pr_err("rc %d from get_system_info\n", rc);4027		goto out;4028	}4029 4030	rc = class_register(&ibmvscsis_class);4031	if (rc) {4032		pr_err("failed class register\n");4033		goto out;4034	}4035 4036	rc = target_register_template(&ibmvscsis_ops);4037	if (rc) {4038		pr_err("rc %d from target_register_template\n", rc);4039		goto unregister_class;4040	}4041 4042	rc = vio_register_driver(&ibmvscsis_driver);4043	if (rc) {4044		pr_err("rc %d from vio_register_driver\n", rc);4045		goto unregister_target;4046	}4047 4048	return 0;4049 4050unregister_target:4051	target_unregister_template(&ibmvscsis_ops);4052unregister_class:4053	class_unregister(&ibmvscsis_class);4054out:4055	return rc;4056}4057 4058static void __exit ibmvscsis_exit(void)4059{4060	pr_info("Unregister IBM virtual SCSI host driver\n");4061	vio_unregister_driver(&ibmvscsis_driver);4062	target_unregister_template(&ibmvscsis_ops);4063	class_unregister(&ibmvscsis_class);4064}4065 4066MODULE_DESCRIPTION("IBMVSCSIS fabric driver");4067MODULE_AUTHOR("Bryant G. Ly and Michael Cyr");4068MODULE_LICENSE("GPL");4069MODULE_VERSION(IBMVSCSIS_VERSION);4070module_init(ibmvscsis_init);4071module_exit(ibmvscsis_exit);4072