brintos

brintos / linux-shallow public Read only

0
0
Text · 283.4 KiB · d91f54a Raw
9957 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * QLogic iSCSI HBA Driver4 * Copyright (c)  2003-2013 QLogic Corporation5 */6#include <linux/moduleparam.h>7#include <linux/slab.h>8#include <linux/blkdev.h>9#include <linux/iscsi_boot_sysfs.h>10#include <linux/inet.h>11 12#include <scsi/scsi_tcq.h>13#include <scsi/scsicam.h>14 15#include "ql4_def.h"16#include "ql4_version.h"17#include "ql4_glbl.h"18#include "ql4_dbg.h"19#include "ql4_inline.h"20#include "ql4_83xx.h"21 22/*23 * Driver version24 */25static char qla4xxx_version_str[40];26 27/*28 * SRB allocation cache29 */30static struct kmem_cache *srb_cachep;31 32/*33 * Module parameter information and variables34 */35static int ql4xdisablesysfsboot = 1;36module_param(ql4xdisablesysfsboot, int, S_IRUGO | S_IWUSR);37MODULE_PARM_DESC(ql4xdisablesysfsboot,38		 " Set to disable exporting boot targets to sysfs.\n"39		 "\t\t  0 - Export boot targets\n"40		 "\t\t  1 - Do not export boot targets (Default)");41 42int ql4xdontresethba;43module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR);44MODULE_PARM_DESC(ql4xdontresethba,45		 " Don't reset the HBA for driver recovery.\n"46		 "\t\t  0 - It will reset HBA (Default)\n"47		 "\t\t  1 - It will NOT reset HBA");48 49int ql4xextended_error_logging;50module_param(ql4xextended_error_logging, int, S_IRUGO | S_IWUSR);51MODULE_PARM_DESC(ql4xextended_error_logging,52		 " Option to enable extended error logging.\n"53		 "\t\t  0 - no logging (Default)\n"54		 "\t\t  2 - debug logging");55 56int ql4xenablemsix = 1;57module_param(ql4xenablemsix, int, S_IRUGO|S_IWUSR);58MODULE_PARM_DESC(ql4xenablemsix,59		 " Set to enable MSI or MSI-X interrupt mechanism.\n"60		 "\t\t  0 = enable INTx interrupt mechanism.\n"61		 "\t\t  1 = enable MSI-X interrupt mechanism (Default).\n"62		 "\t\t  2 = enable MSI interrupt mechanism.");63 64#define QL4_DEF_QDEPTH 3265static int ql4xmaxqdepth = QL4_DEF_QDEPTH;66module_param(ql4xmaxqdepth, int, S_IRUGO | S_IWUSR);67MODULE_PARM_DESC(ql4xmaxqdepth,68		 " Maximum queue depth to report for target devices.\n"69		 "\t\t  Default: 32.");70 71static int ql4xqfulltracking = 1;72module_param(ql4xqfulltracking, int, S_IRUGO | S_IWUSR);73MODULE_PARM_DESC(ql4xqfulltracking,74		 " Enable or disable dynamic tracking and adjustment of\n"75		 "\t\t scsi device queue depth.\n"76		 "\t\t  0 - Disable.\n"77		 "\t\t  1 - Enable. (Default)");78 79static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO;80module_param(ql4xsess_recovery_tmo, int, S_IRUGO);81MODULE_PARM_DESC(ql4xsess_recovery_tmo,82		" Target Session Recovery Timeout.\n"83		"\t\t  Default: 120 sec.");84 85int ql4xmdcapmask = 0;86module_param(ql4xmdcapmask, int, S_IRUGO);87MODULE_PARM_DESC(ql4xmdcapmask,88		 " Set the Minidump driver capture mask level.\n"89		 "\t\t  Default is 0 (firmware default capture mask)\n"90		 "\t\t  Can be set to 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF");91 92int ql4xenablemd = 1;93module_param(ql4xenablemd, int, S_IRUGO | S_IWUSR);94MODULE_PARM_DESC(ql4xenablemd,95		 " Set to enable minidump.\n"96		 "\t\t  0 - disable minidump\n"97		 "\t\t  1 - enable minidump (Default)");98 99static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha);100/*101 * SCSI host template entry points102 */103static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha);104 105/*106 * iSCSI template entry points107 */108static int qla4xxx_session_get_param(struct iscsi_cls_session *cls_sess,109				     enum iscsi_param param, char *buf);110static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn,111				  enum iscsi_param param, char *buf);112static int qla4xxx_host_get_param(struct Scsi_Host *shost,113				  enum iscsi_host_param param, char *buf);114static int qla4xxx_iface_set_param(struct Scsi_Host *shost, void *data,115				   uint32_t len);116static int qla4xxx_get_iface_param(struct iscsi_iface *iface,117				   enum iscsi_param_type param_type,118				   int param, char *buf);119static enum scsi_timeout_action qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc);120static struct iscsi_endpoint *qla4xxx_ep_connect(struct Scsi_Host *shost,121						 struct sockaddr *dst_addr,122						 int non_blocking);123static int qla4xxx_ep_poll(struct iscsi_endpoint *ep, int timeout_ms);124static void qla4xxx_ep_disconnect(struct iscsi_endpoint *ep);125static int qla4xxx_get_ep_param(struct iscsi_endpoint *ep,126				enum iscsi_param param, char *buf);127static int qla4xxx_conn_start(struct iscsi_cls_conn *conn);128static struct iscsi_cls_conn *129qla4xxx_conn_create(struct iscsi_cls_session *cls_sess, uint32_t conn_idx);130static int qla4xxx_conn_bind(struct iscsi_cls_session *cls_session,131			     struct iscsi_cls_conn *cls_conn,132			     uint64_t transport_fd, int is_leading);133static void qla4xxx_conn_destroy(struct iscsi_cls_conn *conn);134static struct iscsi_cls_session *135qla4xxx_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,136			uint16_t qdepth, uint32_t initial_cmdsn);137static void qla4xxx_session_destroy(struct iscsi_cls_session *sess);138static void qla4xxx_task_work(struct work_struct *wdata);139static int qla4xxx_alloc_pdu(struct iscsi_task *, uint8_t);140static int qla4xxx_task_xmit(struct iscsi_task *);141static void qla4xxx_task_cleanup(struct iscsi_task *);142static void qla4xxx_fail_session(struct iscsi_cls_session *cls_session);143static void qla4xxx_conn_get_stats(struct iscsi_cls_conn *cls_conn,144				   struct iscsi_stats *stats);145static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num,146			     uint32_t iface_type, uint32_t payload_size,147			     uint32_t pid, struct sockaddr *dst_addr);148static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx,149				 uint32_t *num_entries, char *buf);150static int qla4xxx_delete_chap(struct Scsi_Host *shost, uint16_t chap_tbl_idx);151static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void  *data,152				  int len);153static int qla4xxx_get_host_stats(struct Scsi_Host *shost, char *buf, int len);154 155/*156 * SCSI host template entry points157 */158static int qla4xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);159static int qla4xxx_eh_abort(struct scsi_cmnd *cmd);160static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd);161static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd);162static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd);163static int qla4xxx_slave_alloc(struct scsi_device *device);164static umode_t qla4_attr_is_visible(int param_type, int param);165static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type);166 167/*168 * iSCSI Flash DDB sysfs entry points169 */170static int171qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess,172			    struct iscsi_bus_flash_conn *fnode_conn,173			    void *data, int len);174static int175qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,176			    int param, char *buf);177static int qla4xxx_sysfs_ddb_add(struct Scsi_Host *shost, const char *buf,178				 int len);179static int180qla4xxx_sysfs_ddb_delete(struct iscsi_bus_flash_session *fnode_sess);181static int qla4xxx_sysfs_ddb_login(struct iscsi_bus_flash_session *fnode_sess,182				   struct iscsi_bus_flash_conn *fnode_conn);183static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess,184				    struct iscsi_bus_flash_conn *fnode_conn);185static int qla4xxx_sysfs_ddb_logout_sid(struct iscsi_cls_session *cls_sess);186 187static struct qla4_8xxx_legacy_intr_set legacy_intr[] =188    QLA82XX_LEGACY_INTR_CONFIG;189 190static const uint32_t qla4_82xx_reg_tbl[] = {191	QLA82XX_PEG_HALT_STATUS1,192	QLA82XX_PEG_HALT_STATUS2,193	QLA82XX_PEG_ALIVE_COUNTER,194	QLA82XX_CRB_DRV_ACTIVE,195	QLA82XX_CRB_DEV_STATE,196	QLA82XX_CRB_DRV_STATE,197	QLA82XX_CRB_DRV_SCRATCH,198	QLA82XX_CRB_DEV_PART_INFO,199	QLA82XX_CRB_DRV_IDC_VERSION,200	QLA82XX_FW_VERSION_MAJOR,201	QLA82XX_FW_VERSION_MINOR,202	QLA82XX_FW_VERSION_SUB,203	CRB_CMDPEG_STATE,204	CRB_TEMP_STATE,205};206 207static const uint32_t qla4_83xx_reg_tbl[] = {208	QLA83XX_PEG_HALT_STATUS1,209	QLA83XX_PEG_HALT_STATUS2,210	QLA83XX_PEG_ALIVE_COUNTER,211	QLA83XX_CRB_DRV_ACTIVE,212	QLA83XX_CRB_DEV_STATE,213	QLA83XX_CRB_DRV_STATE,214	QLA83XX_CRB_DRV_SCRATCH,215	QLA83XX_CRB_DEV_PART_INFO1,216	QLA83XX_CRB_IDC_VER_MAJOR,217	QLA83XX_FW_VER_MAJOR,218	QLA83XX_FW_VER_MINOR,219	QLA83XX_FW_VER_SUB,220	QLA83XX_CMDPEG_STATE,221	QLA83XX_ASIC_TEMP,222};223 224static struct scsi_host_template qla4xxx_driver_template = {225	.module			= THIS_MODULE,226	.name			= DRIVER_NAME,227	.proc_name		= DRIVER_NAME,228	.queuecommand		= qla4xxx_queuecommand,229	.cmd_size		= sizeof(struct qla4xxx_cmd_priv),230 231	.eh_abort_handler	= qla4xxx_eh_abort,232	.eh_device_reset_handler = qla4xxx_eh_device_reset,233	.eh_target_reset_handler = qla4xxx_eh_target_reset,234	.eh_host_reset_handler	= qla4xxx_eh_host_reset,235	.eh_timed_out		= qla4xxx_eh_cmd_timed_out,236 237	.slave_alloc		= qla4xxx_slave_alloc,238	.change_queue_depth	= scsi_change_queue_depth,239 240	.this_id		= -1,241	.cmd_per_lun		= 3,242	.sg_tablesize		= SG_ALL,243 244	.max_sectors		= 0xFFFF,245	.shost_groups		= qla4xxx_host_groups,246	.host_reset		= qla4xxx_host_reset,247	.vendor_id		= SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC,248};249 250static struct iscsi_transport qla4xxx_iscsi_transport = {251	.owner			= THIS_MODULE,252	.name			= DRIVER_NAME,253	.caps			= CAP_TEXT_NEGO |254				  CAP_DATA_PATH_OFFLOAD | CAP_HDRDGST |255				  CAP_DATADGST | CAP_LOGIN_OFFLOAD |256				  CAP_MULTI_R2T,257	.attr_is_visible	= qla4_attr_is_visible,258	.create_session         = qla4xxx_session_create,259	.destroy_session        = qla4xxx_session_destroy,260	.start_conn             = qla4xxx_conn_start,261	.create_conn            = qla4xxx_conn_create,262	.bind_conn              = qla4xxx_conn_bind,263	.unbind_conn		= iscsi_conn_unbind,264	.stop_conn              = iscsi_conn_stop,265	.destroy_conn           = qla4xxx_conn_destroy,266	.set_param              = iscsi_set_param,267	.get_conn_param		= qla4xxx_conn_get_param,268	.get_session_param	= qla4xxx_session_get_param,269	.get_ep_param           = qla4xxx_get_ep_param,270	.ep_connect		= qla4xxx_ep_connect,271	.ep_poll		= qla4xxx_ep_poll,272	.ep_disconnect		= qla4xxx_ep_disconnect,273	.get_stats		= qla4xxx_conn_get_stats,274	.send_pdu		= iscsi_conn_send_pdu,275	.xmit_task		= qla4xxx_task_xmit,276	.cleanup_task		= qla4xxx_task_cleanup,277	.alloc_pdu		= qla4xxx_alloc_pdu,278 279	.get_host_param		= qla4xxx_host_get_param,280	.set_iface_param	= qla4xxx_iface_set_param,281	.get_iface_param	= qla4xxx_get_iface_param,282	.bsg_request		= qla4xxx_bsg_request,283	.send_ping		= qla4xxx_send_ping,284	.get_chap		= qla4xxx_get_chap_list,285	.delete_chap		= qla4xxx_delete_chap,286	.set_chap		= qla4xxx_set_chap_entry,287	.get_flashnode_param	= qla4xxx_sysfs_ddb_get_param,288	.set_flashnode_param	= qla4xxx_sysfs_ddb_set_param,289	.new_flashnode		= qla4xxx_sysfs_ddb_add,290	.del_flashnode		= qla4xxx_sysfs_ddb_delete,291	.login_flashnode	= qla4xxx_sysfs_ddb_login,292	.logout_flashnode	= qla4xxx_sysfs_ddb_logout,293	.logout_flashnode_sid	= qla4xxx_sysfs_ddb_logout_sid,294	.get_host_stats		= qla4xxx_get_host_stats,295};296 297static struct scsi_transport_template *qla4xxx_scsi_transport;298 299static int qla4xxx_isp_check_reg(struct scsi_qla_host *ha)300{301	u32 reg_val = 0;302	int rval = QLA_SUCCESS;303 304	if (is_qla8022(ha))305		reg_val = readl(&ha->qla4_82xx_reg->host_status);306	else if (is_qla8032(ha) || is_qla8042(ha))307		reg_val = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);308	else309		reg_val = readw(&ha->reg->ctrl_status);310 311	if (reg_val == QL4_ISP_REG_DISCONNECT)312		rval = QLA_ERROR;313 314	return rval;315}316 317static int qla4xxx_send_ping(struct Scsi_Host *shost, uint32_t iface_num,318			     uint32_t iface_type, uint32_t payload_size,319			     uint32_t pid, struct sockaddr *dst_addr)320{321	struct scsi_qla_host *ha = to_qla_host(shost);322	struct sockaddr_in *addr;323	struct sockaddr_in6 *addr6;324	uint32_t options = 0;325	uint8_t ipaddr[IPv6_ADDR_LEN];326	int rval;327 328	memset(ipaddr, 0, IPv6_ADDR_LEN);329	/* IPv4 to IPv4 */330	if ((iface_type == ISCSI_IFACE_TYPE_IPV4) &&331	    (dst_addr->sa_family == AF_INET)) {332		addr = (struct sockaddr_in *)dst_addr;333		memcpy(ipaddr, &addr->sin_addr.s_addr, IP_ADDR_LEN);334		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IPv4 Ping src: %pI4 "335				  "dest: %pI4\n", __func__,336				  &ha->ip_config.ip_address, ipaddr));337		rval = qla4xxx_ping_iocb(ha, options, payload_size, pid,338					 ipaddr);339		if (rval)340			rval = -EINVAL;341	} else if ((iface_type == ISCSI_IFACE_TYPE_IPV6) &&342		   (dst_addr->sa_family == AF_INET6)) {343		/* IPv6 to IPv6 */344		addr6 = (struct sockaddr_in6 *)dst_addr;345		memcpy(ipaddr, &addr6->sin6_addr.in6_u.u6_addr8, IPv6_ADDR_LEN);346 347		options |= PING_IPV6_PROTOCOL_ENABLE;348 349		/* Ping using LinkLocal address */350		if ((iface_num == 0) || (iface_num == 1)) {351			DEBUG2(ql4_printk(KERN_INFO, ha, "%s: LinkLocal Ping "352					  "src: %pI6 dest: %pI6\n", __func__,353					  &ha->ip_config.ipv6_link_local_addr,354					  ipaddr));355			options |= PING_IPV6_LINKLOCAL_ADDR;356			rval = qla4xxx_ping_iocb(ha, options, payload_size,357						 pid, ipaddr);358		} else {359			ql4_printk(KERN_WARNING, ha, "%s: iface num = %d "360				   "not supported\n", __func__, iface_num);361			rval = -ENOSYS;362			goto exit_send_ping;363		}364 365		/*366		 * If ping using LinkLocal address fails, try ping using367		 * IPv6 address368		 */369		if (rval != QLA_SUCCESS) {370			options &= ~PING_IPV6_LINKLOCAL_ADDR;371			if (iface_num == 0) {372				options |= PING_IPV6_ADDR0;373				DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IPv6 "374						  "Ping src: %pI6 "375						  "dest: %pI6\n", __func__,376						  &ha->ip_config.ipv6_addr0,377						  ipaddr));378			} else if (iface_num == 1) {379				options |= PING_IPV6_ADDR1;380				DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IPv6 "381						  "Ping src: %pI6 "382						  "dest: %pI6\n", __func__,383						  &ha->ip_config.ipv6_addr1,384						  ipaddr));385			}386			rval = qla4xxx_ping_iocb(ha, options, payload_size,387						 pid, ipaddr);388			if (rval)389				rval = -EINVAL;390		}391	} else392		rval = -ENOSYS;393exit_send_ping:394	return rval;395}396 397static umode_t qla4_attr_is_visible(int param_type, int param)398{399	switch (param_type) {400	case ISCSI_HOST_PARAM:401		switch (param) {402		case ISCSI_HOST_PARAM_HWADDRESS:403		case ISCSI_HOST_PARAM_IPADDRESS:404		case ISCSI_HOST_PARAM_INITIATOR_NAME:405		case ISCSI_HOST_PARAM_PORT_STATE:406		case ISCSI_HOST_PARAM_PORT_SPEED:407			return S_IRUGO;408		default:409			return 0;410		}411	case ISCSI_PARAM:412		switch (param) {413		case ISCSI_PARAM_PERSISTENT_ADDRESS:414		case ISCSI_PARAM_PERSISTENT_PORT:415		case ISCSI_PARAM_CONN_ADDRESS:416		case ISCSI_PARAM_CONN_PORT:417		case ISCSI_PARAM_TARGET_NAME:418		case ISCSI_PARAM_TPGT:419		case ISCSI_PARAM_TARGET_ALIAS:420		case ISCSI_PARAM_MAX_BURST:421		case ISCSI_PARAM_MAX_R2T:422		case ISCSI_PARAM_FIRST_BURST:423		case ISCSI_PARAM_MAX_RECV_DLENGTH:424		case ISCSI_PARAM_MAX_XMIT_DLENGTH:425		case ISCSI_PARAM_IFACE_NAME:426		case ISCSI_PARAM_CHAP_OUT_IDX:427		case ISCSI_PARAM_CHAP_IN_IDX:428		case ISCSI_PARAM_USERNAME:429		case ISCSI_PARAM_PASSWORD:430		case ISCSI_PARAM_USERNAME_IN:431		case ISCSI_PARAM_PASSWORD_IN:432		case ISCSI_PARAM_AUTO_SND_TGT_DISABLE:433		case ISCSI_PARAM_DISCOVERY_SESS:434		case ISCSI_PARAM_PORTAL_TYPE:435		case ISCSI_PARAM_CHAP_AUTH_EN:436		case ISCSI_PARAM_DISCOVERY_LOGOUT_EN:437		case ISCSI_PARAM_BIDI_CHAP_EN:438		case ISCSI_PARAM_DISCOVERY_AUTH_OPTIONAL:439		case ISCSI_PARAM_DEF_TIME2WAIT:440		case ISCSI_PARAM_DEF_TIME2RETAIN:441		case ISCSI_PARAM_HDRDGST_EN:442		case ISCSI_PARAM_DATADGST_EN:443		case ISCSI_PARAM_INITIAL_R2T_EN:444		case ISCSI_PARAM_IMM_DATA_EN:445		case ISCSI_PARAM_PDU_INORDER_EN:446		case ISCSI_PARAM_DATASEQ_INORDER_EN:447		case ISCSI_PARAM_MAX_SEGMENT_SIZE:448		case ISCSI_PARAM_TCP_TIMESTAMP_STAT:449		case ISCSI_PARAM_TCP_WSF_DISABLE:450		case ISCSI_PARAM_TCP_NAGLE_DISABLE:451		case ISCSI_PARAM_TCP_TIMER_SCALE:452		case ISCSI_PARAM_TCP_TIMESTAMP_EN:453		case ISCSI_PARAM_TCP_XMIT_WSF:454		case ISCSI_PARAM_TCP_RECV_WSF:455		case ISCSI_PARAM_IP_FRAGMENT_DISABLE:456		case ISCSI_PARAM_IPV4_TOS:457		case ISCSI_PARAM_IPV6_TC:458		case ISCSI_PARAM_IPV6_FLOW_LABEL:459		case ISCSI_PARAM_IS_FW_ASSIGNED_IPV6:460		case ISCSI_PARAM_KEEPALIVE_TMO:461		case ISCSI_PARAM_LOCAL_PORT:462		case ISCSI_PARAM_ISID:463		case ISCSI_PARAM_TSID:464		case ISCSI_PARAM_DEF_TASKMGMT_TMO:465		case ISCSI_PARAM_ERL:466		case ISCSI_PARAM_STATSN:467		case ISCSI_PARAM_EXP_STATSN:468		case ISCSI_PARAM_DISCOVERY_PARENT_IDX:469		case ISCSI_PARAM_DISCOVERY_PARENT_TYPE:470		case ISCSI_PARAM_LOCAL_IPADDR:471			return S_IRUGO;472		default:473			return 0;474		}475	case ISCSI_NET_PARAM:476		switch (param) {477		case ISCSI_NET_PARAM_IPV4_ADDR:478		case ISCSI_NET_PARAM_IPV4_SUBNET:479		case ISCSI_NET_PARAM_IPV4_GW:480		case ISCSI_NET_PARAM_IPV4_BOOTPROTO:481		case ISCSI_NET_PARAM_IFACE_ENABLE:482		case ISCSI_NET_PARAM_IPV6_LINKLOCAL:483		case ISCSI_NET_PARAM_IPV6_ADDR:484		case ISCSI_NET_PARAM_IPV6_ROUTER:485		case ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG:486		case ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG:487		case ISCSI_NET_PARAM_VLAN_ID:488		case ISCSI_NET_PARAM_VLAN_PRIORITY:489		case ISCSI_NET_PARAM_VLAN_ENABLED:490		case ISCSI_NET_PARAM_MTU:491		case ISCSI_NET_PARAM_PORT:492		case ISCSI_NET_PARAM_IPADDR_STATE:493		case ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE:494		case ISCSI_NET_PARAM_IPV6_ROUTER_STATE:495		case ISCSI_NET_PARAM_DELAYED_ACK_EN:496		case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE:497		case ISCSI_NET_PARAM_TCP_WSF_DISABLE:498		case ISCSI_NET_PARAM_TCP_WSF:499		case ISCSI_NET_PARAM_TCP_TIMER_SCALE:500		case ISCSI_NET_PARAM_TCP_TIMESTAMP_EN:501		case ISCSI_NET_PARAM_CACHE_ID:502		case ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN:503		case ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN:504		case ISCSI_NET_PARAM_IPV4_TOS_EN:505		case ISCSI_NET_PARAM_IPV4_TOS:506		case ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN:507		case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN:508		case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID:509		case ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN:510		case ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN:511		case ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID:512		case ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN:513		case ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE:514		case ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN:515		case ISCSI_NET_PARAM_REDIRECT_EN:516		case ISCSI_NET_PARAM_IPV4_TTL:517		case ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN:518		case ISCSI_NET_PARAM_IPV6_MLD_EN:519		case ISCSI_NET_PARAM_IPV6_FLOW_LABEL:520		case ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS:521		case ISCSI_NET_PARAM_IPV6_HOP_LIMIT:522		case ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO:523		case ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME:524		case ISCSI_NET_PARAM_IPV6_ND_STALE_TMO:525		case ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT:526		case ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU:527			return S_IRUGO;528		default:529			return 0;530		}531	case ISCSI_IFACE_PARAM:532		switch (param) {533		case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO:534		case ISCSI_IFACE_PARAM_HDRDGST_EN:535		case ISCSI_IFACE_PARAM_DATADGST_EN:536		case ISCSI_IFACE_PARAM_IMM_DATA_EN:537		case ISCSI_IFACE_PARAM_INITIAL_R2T_EN:538		case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN:539		case ISCSI_IFACE_PARAM_PDU_INORDER_EN:540		case ISCSI_IFACE_PARAM_ERL:541		case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH:542		case ISCSI_IFACE_PARAM_FIRST_BURST:543		case ISCSI_IFACE_PARAM_MAX_R2T:544		case ISCSI_IFACE_PARAM_MAX_BURST:545		case ISCSI_IFACE_PARAM_CHAP_AUTH_EN:546		case ISCSI_IFACE_PARAM_BIDI_CHAP_EN:547		case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL:548		case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN:549		case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN:550		case ISCSI_IFACE_PARAM_INITIATOR_NAME:551			return S_IRUGO;552		default:553			return 0;554		}555	case ISCSI_FLASHNODE_PARAM:556		switch (param) {557		case ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6:558		case ISCSI_FLASHNODE_PORTAL_TYPE:559		case ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE:560		case ISCSI_FLASHNODE_DISCOVERY_SESS:561		case ISCSI_FLASHNODE_ENTRY_EN:562		case ISCSI_FLASHNODE_HDR_DGST_EN:563		case ISCSI_FLASHNODE_DATA_DGST_EN:564		case ISCSI_FLASHNODE_IMM_DATA_EN:565		case ISCSI_FLASHNODE_INITIAL_R2T_EN:566		case ISCSI_FLASHNODE_DATASEQ_INORDER:567		case ISCSI_FLASHNODE_PDU_INORDER:568		case ISCSI_FLASHNODE_CHAP_AUTH_EN:569		case ISCSI_FLASHNODE_SNACK_REQ_EN:570		case ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN:571		case ISCSI_FLASHNODE_BIDI_CHAP_EN:572		case ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL:573		case ISCSI_FLASHNODE_ERL:574		case ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT:575		case ISCSI_FLASHNODE_TCP_NAGLE_DISABLE:576		case ISCSI_FLASHNODE_TCP_WSF_DISABLE:577		case ISCSI_FLASHNODE_TCP_TIMER_SCALE:578		case ISCSI_FLASHNODE_TCP_TIMESTAMP_EN:579		case ISCSI_FLASHNODE_IP_FRAG_DISABLE:580		case ISCSI_FLASHNODE_MAX_RECV_DLENGTH:581		case ISCSI_FLASHNODE_MAX_XMIT_DLENGTH:582		case ISCSI_FLASHNODE_FIRST_BURST:583		case ISCSI_FLASHNODE_DEF_TIME2WAIT:584		case ISCSI_FLASHNODE_DEF_TIME2RETAIN:585		case ISCSI_FLASHNODE_MAX_R2T:586		case ISCSI_FLASHNODE_KEEPALIVE_TMO:587		case ISCSI_FLASHNODE_ISID:588		case ISCSI_FLASHNODE_TSID:589		case ISCSI_FLASHNODE_PORT:590		case ISCSI_FLASHNODE_MAX_BURST:591		case ISCSI_FLASHNODE_DEF_TASKMGMT_TMO:592		case ISCSI_FLASHNODE_IPADDR:593		case ISCSI_FLASHNODE_ALIAS:594		case ISCSI_FLASHNODE_REDIRECT_IPADDR:595		case ISCSI_FLASHNODE_MAX_SEGMENT_SIZE:596		case ISCSI_FLASHNODE_LOCAL_PORT:597		case ISCSI_FLASHNODE_IPV4_TOS:598		case ISCSI_FLASHNODE_IPV6_TC:599		case ISCSI_FLASHNODE_IPV6_FLOW_LABEL:600		case ISCSI_FLASHNODE_NAME:601		case ISCSI_FLASHNODE_TPGT:602		case ISCSI_FLASHNODE_LINK_LOCAL_IPV6:603		case ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX:604		case ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE:605		case ISCSI_FLASHNODE_TCP_XMIT_WSF:606		case ISCSI_FLASHNODE_TCP_RECV_WSF:607		case ISCSI_FLASHNODE_CHAP_OUT_IDX:608		case ISCSI_FLASHNODE_USERNAME:609		case ISCSI_FLASHNODE_PASSWORD:610		case ISCSI_FLASHNODE_STATSN:611		case ISCSI_FLASHNODE_EXP_STATSN:612		case ISCSI_FLASHNODE_IS_BOOT_TGT:613			return S_IRUGO;614		default:615			return 0;616		}617	}618 619	return 0;620}621 622/**623 * qla4xxx_create_chap_list - Create CHAP list from FLASH624 * @ha: pointer to adapter structure625 *626 * Read flash and make a list of CHAP entries, during login when a CHAP entry627 * is received, it will be checked in this list. If entry exist then the CHAP628 * entry index is set in the DDB. If CHAP entry does not exist in this list629 * then a new entry is added in FLASH in CHAP table and the index obtained is630 * used in the DDB.631 **/632static void qla4xxx_create_chap_list(struct scsi_qla_host *ha)633{634	int rval = 0;635	uint8_t *chap_flash_data = NULL;636	uint32_t offset;637	dma_addr_t chap_dma;638	uint32_t chap_size = 0;639 640	if (is_qla40XX(ha))641		chap_size = MAX_CHAP_ENTRIES_40XX *642			    sizeof(struct ql4_chap_table);643	else	/* Single region contains CHAP info for both644		 * ports which is divided into half for each port.645		 */646		chap_size = ha->hw.flt_chap_size / 2;647 648	chap_flash_data = dma_alloc_coherent(&ha->pdev->dev, chap_size,649					     &chap_dma, GFP_KERNEL);650	if (!chap_flash_data) {651		ql4_printk(KERN_ERR, ha, "No memory for chap_flash_data\n");652		return;653	}654 655	if (is_qla40XX(ha)) {656		offset = FLASH_CHAP_OFFSET;657	} else {658		offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);659		if (ha->port_num == 1)660			offset += chap_size;661	}662 663	rval = qla4xxx_get_flash(ha, chap_dma, offset, chap_size);664	if (rval != QLA_SUCCESS)665		goto exit_chap_list;666 667	if (ha->chap_list == NULL)668		ha->chap_list = vmalloc(chap_size);669	if (ha->chap_list == NULL) {670		ql4_printk(KERN_ERR, ha, "No memory for ha->chap_list\n");671		goto exit_chap_list;672	}673 674	memcpy(ha->chap_list, chap_flash_data, chap_size);675 676exit_chap_list:677	dma_free_coherent(&ha->pdev->dev, chap_size, chap_flash_data, chap_dma);678}679 680static int qla4xxx_get_chap_by_index(struct scsi_qla_host *ha,681				     int16_t chap_index,682				     struct ql4_chap_table **chap_entry)683{684	int rval = QLA_ERROR;685	int max_chap_entries;686 687	if (!ha->chap_list) {688		ql4_printk(KERN_ERR, ha, "CHAP table cache is empty!\n");689		goto exit_get_chap;690	}691 692	if (is_qla80XX(ha))693		max_chap_entries = (ha->hw.flt_chap_size / 2) /694				   sizeof(struct ql4_chap_table);695	else696		max_chap_entries = MAX_CHAP_ENTRIES_40XX;697 698	if (chap_index > max_chap_entries) {699		ql4_printk(KERN_ERR, ha, "Invalid Chap index\n");700		goto exit_get_chap;701	}702 703	*chap_entry = (struct ql4_chap_table *)ha->chap_list + chap_index;704	if ((*chap_entry)->cookie !=705	     cpu_to_le16(CHAP_VALID_COOKIE)) {706		*chap_entry = NULL;707	} else {708		rval = QLA_SUCCESS;709	}710 711exit_get_chap:712	return rval;713}714 715/**716 * qla4xxx_find_free_chap_index - Find the first free chap index717 * @ha: pointer to adapter structure718 * @chap_index: CHAP index to be returned719 *720 * Find the first free chap index available in the chap table721 *722 * Note: Caller should acquire the chap lock before getting here.723 **/724static int qla4xxx_find_free_chap_index(struct scsi_qla_host *ha,725					uint16_t *chap_index)726{727	int i, rval;728	int free_index = -1;729	int max_chap_entries = 0;730	struct ql4_chap_table *chap_table;731 732	if (is_qla80XX(ha))733		max_chap_entries = (ha->hw.flt_chap_size / 2) /734						sizeof(struct ql4_chap_table);735	else736		max_chap_entries = MAX_CHAP_ENTRIES_40XX;737 738	if (!ha->chap_list) {739		ql4_printk(KERN_ERR, ha, "CHAP table cache is empty!\n");740		rval = QLA_ERROR;741		goto exit_find_chap;742	}743 744	for (i = 0; i < max_chap_entries; i++) {745		chap_table = (struct ql4_chap_table *)ha->chap_list + i;746 747		if ((chap_table->cookie !=748		    cpu_to_le16(CHAP_VALID_COOKIE)) &&749		   (i > MAX_RESRV_CHAP_IDX)) {750				free_index = i;751				break;752		}753	}754 755	if (free_index != -1) {756		*chap_index = free_index;757		rval = QLA_SUCCESS;758	} else {759		rval = QLA_ERROR;760	}761 762exit_find_chap:763	return rval;764}765 766static int qla4xxx_get_chap_list(struct Scsi_Host *shost, uint16_t chap_tbl_idx,767				  uint32_t *num_entries, char *buf)768{769	struct scsi_qla_host *ha = to_qla_host(shost);770	struct ql4_chap_table *chap_table;771	struct iscsi_chap_rec *chap_rec;772	int max_chap_entries = 0;773	int valid_chap_entries = 0;774	int ret = 0, i;775 776	if (is_qla80XX(ha))777		max_chap_entries = (ha->hw.flt_chap_size / 2) /778					sizeof(struct ql4_chap_table);779	else780		max_chap_entries = MAX_CHAP_ENTRIES_40XX;781 782	ql4_printk(KERN_INFO, ha, "%s: num_entries = %d, CHAP idx = %d\n",783			__func__, *num_entries, chap_tbl_idx);784 785	if (!buf) {786		ret = -ENOMEM;787		goto exit_get_chap_list;788	}789 790	qla4xxx_create_chap_list(ha);791 792	chap_rec = (struct iscsi_chap_rec *) buf;793	mutex_lock(&ha->chap_sem);794	for (i = chap_tbl_idx; i < max_chap_entries; i++) {795		chap_table = (struct ql4_chap_table *)ha->chap_list + i;796		if (chap_table->cookie !=797		    cpu_to_le16(CHAP_VALID_COOKIE))798			continue;799 800		chap_rec->chap_tbl_idx = i;801		strscpy(chap_rec->username, chap_table->name,802			sizeof(chap_rec->username));803		chap_rec->password_length = strscpy(chap_rec->password,804						    chap_table->secret,805						    sizeof(chap_rec->password));806 807		if (chap_table->flags & BIT_7) /* local */808			chap_rec->chap_type = CHAP_TYPE_OUT;809 810		if (chap_table->flags & BIT_6) /* peer */811			chap_rec->chap_type = CHAP_TYPE_IN;812 813		chap_rec++;814 815		valid_chap_entries++;816		if (valid_chap_entries == *num_entries)817			break;818	}819	mutex_unlock(&ha->chap_sem);820 821exit_get_chap_list:822	ql4_printk(KERN_INFO, ha, "%s: Valid CHAP Entries = %d\n",823			__func__,  valid_chap_entries);824	*num_entries = valid_chap_entries;825	return ret;826}827 828static int __qla4xxx_is_chap_active(struct device *dev, void *data)829{830	int ret = 0;831	uint16_t *chap_tbl_idx = (uint16_t *) data;832	struct iscsi_cls_session *cls_session;833	struct iscsi_session *sess;834	struct ddb_entry *ddb_entry;835 836	if (!iscsi_is_session_dev(dev))837		goto exit_is_chap_active;838 839	cls_session = iscsi_dev_to_session(dev);840	sess = cls_session->dd_data;841	ddb_entry = sess->dd_data;842 843	if (iscsi_is_session_online(cls_session))844		goto exit_is_chap_active;845 846	if (ddb_entry->chap_tbl_idx == *chap_tbl_idx)847		ret = 1;848 849exit_is_chap_active:850	return ret;851}852 853static int qla4xxx_is_chap_active(struct Scsi_Host *shost,854				  uint16_t chap_tbl_idx)855{856	int ret = 0;857 858	ret = device_for_each_child(&shost->shost_gendev, &chap_tbl_idx,859				    __qla4xxx_is_chap_active);860 861	return ret;862}863 864static int qla4xxx_delete_chap(struct Scsi_Host *shost, uint16_t chap_tbl_idx)865{866	struct scsi_qla_host *ha = to_qla_host(shost);867	struct ql4_chap_table *chap_table;868	dma_addr_t chap_dma;869	int max_chap_entries = 0;870	uint32_t offset = 0;871	uint32_t chap_size;872	int ret = 0;873 874	chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);875	if (chap_table == NULL)876		return -ENOMEM;877 878	if (is_qla80XX(ha))879		max_chap_entries = (ha->hw.flt_chap_size / 2) /880				   sizeof(struct ql4_chap_table);881	else882		max_chap_entries = MAX_CHAP_ENTRIES_40XX;883 884	if (chap_tbl_idx > max_chap_entries) {885		ret = -EINVAL;886		goto exit_delete_chap;887	}888 889	/* Check if chap index is in use.890	 * If chap is in use don't delet chap entry */891	ret = qla4xxx_is_chap_active(shost, chap_tbl_idx);892	if (ret) {893		ql4_printk(KERN_INFO, ha, "CHAP entry %d is in use, cannot "894			   "delete from flash\n", chap_tbl_idx);895		ret = -EBUSY;896		goto exit_delete_chap;897	}898 899	chap_size = sizeof(struct ql4_chap_table);900	if (is_qla40XX(ha))901		offset = FLASH_CHAP_OFFSET | (chap_tbl_idx * chap_size);902	else {903		offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);904		/* flt_chap_size is CHAP table size for both ports905		 * so divide it by 2 to calculate the offset for second port906		 */907		if (ha->port_num == 1)908			offset += (ha->hw.flt_chap_size / 2);909		offset += (chap_tbl_idx * chap_size);910	}911 912	ret = qla4xxx_get_flash(ha, chap_dma, offset, chap_size);913	if (ret != QLA_SUCCESS) {914		ret = -EINVAL;915		goto exit_delete_chap;916	}917 918	DEBUG2(ql4_printk(KERN_INFO, ha, "Chap Cookie: x%x\n",919			  __le16_to_cpu(chap_table->cookie)));920 921	if (__le16_to_cpu(chap_table->cookie) != CHAP_VALID_COOKIE) {922		ql4_printk(KERN_ERR, ha, "No valid chap entry found\n");923		goto exit_delete_chap;924	}925 926	chap_table->cookie = cpu_to_le16(0xFFFF);927 928	offset = FLASH_CHAP_OFFSET |929			(chap_tbl_idx * sizeof(struct ql4_chap_table));930	ret = qla4xxx_set_flash(ha, chap_dma, offset, chap_size,931				FLASH_OPT_RMW_COMMIT);932	if (ret == QLA_SUCCESS && ha->chap_list) {933		mutex_lock(&ha->chap_sem);934		/* Update ha chap_list cache */935		memcpy((struct ql4_chap_table *)ha->chap_list + chap_tbl_idx,936			chap_table, sizeof(struct ql4_chap_table));937		mutex_unlock(&ha->chap_sem);938	}939	if (ret != QLA_SUCCESS)940		ret =  -EINVAL;941 942exit_delete_chap:943	dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma);944	return ret;945}946 947/**948 * qla4xxx_set_chap_entry - Make chap entry with given information949 * @shost: pointer to host950 * @data: chap info - credentials, index and type to make chap entry951 * @len: length of data952 *953 * Add or update chap entry with the given information954 **/955static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void *data, int len)956{957	struct scsi_qla_host *ha = to_qla_host(shost);958	struct iscsi_chap_rec chap_rec;959	struct ql4_chap_table *chap_entry = NULL;960	struct iscsi_param_info *param_info;961	struct nlattr *attr;962	int max_chap_entries = 0;963	int type;964	int rem = len;965	int rc = 0;966	int size;967 968	memset(&chap_rec, 0, sizeof(chap_rec));969 970	nla_for_each_attr(attr, data, len, rem) {971		if (nla_len(attr) < sizeof(*param_info)) {972			rc = -EINVAL;973			goto exit_set_chap;974		}975 976		param_info = nla_data(attr);977 978		switch (param_info->param) {979		case ISCSI_CHAP_PARAM_INDEX:980			chap_rec.chap_tbl_idx = *(uint16_t *)param_info->value;981			break;982		case ISCSI_CHAP_PARAM_CHAP_TYPE:983			chap_rec.chap_type = param_info->value[0];984			break;985		case ISCSI_CHAP_PARAM_USERNAME:986			size = min_t(size_t, sizeof(chap_rec.username),987				     param_info->len);988			memcpy(chap_rec.username, param_info->value, size);989			break;990		case ISCSI_CHAP_PARAM_PASSWORD:991			size = min_t(size_t, sizeof(chap_rec.password),992				     param_info->len);993			memcpy(chap_rec.password, param_info->value, size);994			break;995		case ISCSI_CHAP_PARAM_PASSWORD_LEN:996			chap_rec.password_length = param_info->value[0];997			break;998		default:999			ql4_printk(KERN_ERR, ha,1000				   "%s: No such sysfs attribute\n", __func__);1001			rc = -ENOSYS;1002			goto exit_set_chap;1003		}1004	}1005 1006	if (chap_rec.chap_type == CHAP_TYPE_IN)1007		type = BIDI_CHAP;1008	else1009		type = LOCAL_CHAP;1010 1011	if (is_qla80XX(ha))1012		max_chap_entries = (ha->hw.flt_chap_size / 2) /1013				   sizeof(struct ql4_chap_table);1014	else1015		max_chap_entries = MAX_CHAP_ENTRIES_40XX;1016 1017	mutex_lock(&ha->chap_sem);1018	if (chap_rec.chap_tbl_idx < max_chap_entries) {1019		rc = qla4xxx_get_chap_by_index(ha, chap_rec.chap_tbl_idx,1020					       &chap_entry);1021		if (!rc) {1022			if (!(type == qla4xxx_get_chap_type(chap_entry))) {1023				ql4_printk(KERN_INFO, ha,1024					   "Type mismatch for CHAP entry %d\n",1025					   chap_rec.chap_tbl_idx);1026				rc = -EINVAL;1027				goto exit_unlock_chap;1028			}1029 1030			/* If chap index is in use then don't modify it */1031			rc = qla4xxx_is_chap_active(shost,1032						    chap_rec.chap_tbl_idx);1033			if (rc) {1034				ql4_printk(KERN_INFO, ha,1035					   "CHAP entry %d is in use\n",1036					   chap_rec.chap_tbl_idx);1037				rc = -EBUSY;1038				goto exit_unlock_chap;1039			}1040		}1041	} else {1042		rc = qla4xxx_find_free_chap_index(ha, &chap_rec.chap_tbl_idx);1043		if (rc) {1044			ql4_printk(KERN_INFO, ha, "CHAP entry not available\n");1045			rc = -EBUSY;1046			goto exit_unlock_chap;1047		}1048	}1049 1050	rc = qla4xxx_set_chap(ha, chap_rec.username, chap_rec.password,1051			      chap_rec.chap_tbl_idx, type);1052 1053exit_unlock_chap:1054	mutex_unlock(&ha->chap_sem);1055 1056exit_set_chap:1057	return rc;1058}1059 1060 1061static int qla4xxx_get_host_stats(struct Scsi_Host *shost, char *buf, int len)1062{1063	struct scsi_qla_host *ha = to_qla_host(shost);1064	struct iscsi_offload_host_stats *host_stats = NULL;1065	int host_stats_size;1066	int ret = 0;1067	int ddb_idx = 0;1068	struct ql_iscsi_stats *ql_iscsi_stats = NULL;1069	int stats_size;1070	dma_addr_t iscsi_stats_dma;1071 1072	DEBUG2(ql4_printk(KERN_INFO, ha, "Func: %s\n", __func__));1073 1074	host_stats_size = sizeof(struct iscsi_offload_host_stats);1075 1076	if (host_stats_size != len) {1077		ql4_printk(KERN_INFO, ha, "%s: host_stats size mismatch expected = %d, is = %d\n",1078			   __func__, len, host_stats_size);1079		ret = -EINVAL;1080		goto exit_host_stats;1081	}1082	host_stats = (struct iscsi_offload_host_stats *)buf;1083 1084	if (!buf) {1085		ret = -ENOMEM;1086		goto exit_host_stats;1087	}1088 1089	stats_size = PAGE_ALIGN(sizeof(struct ql_iscsi_stats));1090 1091	ql_iscsi_stats = dma_alloc_coherent(&ha->pdev->dev, stats_size,1092					    &iscsi_stats_dma, GFP_KERNEL);1093	if (!ql_iscsi_stats) {1094		ql4_printk(KERN_ERR, ha,1095			   "Unable to allocate memory for iscsi stats\n");1096		ret = -ENOMEM;1097		goto exit_host_stats;1098	}1099 1100	ret =  qla4xxx_get_mgmt_data(ha, ddb_idx, stats_size,1101				     iscsi_stats_dma);1102	if (ret != QLA_SUCCESS) {1103		ql4_printk(KERN_ERR, ha,1104			   "Unable to retrieve iscsi stats\n");1105		ret = -EIO;1106		goto exit_host_stats;1107	}1108	host_stats->mactx_frames = le64_to_cpu(ql_iscsi_stats->mac_tx_frames);1109	host_stats->mactx_bytes = le64_to_cpu(ql_iscsi_stats->mac_tx_bytes);1110	host_stats->mactx_multicast_frames =1111			le64_to_cpu(ql_iscsi_stats->mac_tx_multicast_frames);1112	host_stats->mactx_broadcast_frames =1113			le64_to_cpu(ql_iscsi_stats->mac_tx_broadcast_frames);1114	host_stats->mactx_pause_frames =1115			le64_to_cpu(ql_iscsi_stats->mac_tx_pause_frames);1116	host_stats->mactx_control_frames =1117			le64_to_cpu(ql_iscsi_stats->mac_tx_control_frames);1118	host_stats->mactx_deferral =1119			le64_to_cpu(ql_iscsi_stats->mac_tx_deferral);1120	host_stats->mactx_excess_deferral =1121			le64_to_cpu(ql_iscsi_stats->mac_tx_excess_deferral);1122	host_stats->mactx_late_collision =1123			le64_to_cpu(ql_iscsi_stats->mac_tx_late_collision);1124	host_stats->mactx_abort	= le64_to_cpu(ql_iscsi_stats->mac_tx_abort);1125	host_stats->mactx_single_collision =1126			le64_to_cpu(ql_iscsi_stats->mac_tx_single_collision);1127	host_stats->mactx_multiple_collision =1128			le64_to_cpu(ql_iscsi_stats->mac_tx_multiple_collision);1129	host_stats->mactx_collision =1130			le64_to_cpu(ql_iscsi_stats->mac_tx_collision);1131	host_stats->mactx_frames_dropped =1132			le64_to_cpu(ql_iscsi_stats->mac_tx_frames_dropped);1133	host_stats->mactx_jumbo_frames =1134			le64_to_cpu(ql_iscsi_stats->mac_tx_jumbo_frames);1135	host_stats->macrx_frames = le64_to_cpu(ql_iscsi_stats->mac_rx_frames);1136	host_stats->macrx_bytes = le64_to_cpu(ql_iscsi_stats->mac_rx_bytes);1137	host_stats->macrx_unknown_control_frames =1138		le64_to_cpu(ql_iscsi_stats->mac_rx_unknown_control_frames);1139	host_stats->macrx_pause_frames =1140			le64_to_cpu(ql_iscsi_stats->mac_rx_pause_frames);1141	host_stats->macrx_control_frames =1142			le64_to_cpu(ql_iscsi_stats->mac_rx_control_frames);1143	host_stats->macrx_dribble =1144			le64_to_cpu(ql_iscsi_stats->mac_rx_dribble);1145	host_stats->macrx_frame_length_error =1146			le64_to_cpu(ql_iscsi_stats->mac_rx_frame_length_error);1147	host_stats->macrx_jabber = le64_to_cpu(ql_iscsi_stats->mac_rx_jabber);1148	host_stats->macrx_carrier_sense_error =1149		le64_to_cpu(ql_iscsi_stats->mac_rx_carrier_sense_error);1150	host_stats->macrx_frame_discarded =1151			le64_to_cpu(ql_iscsi_stats->mac_rx_frame_discarded);1152	host_stats->macrx_frames_dropped =1153			le64_to_cpu(ql_iscsi_stats->mac_rx_frames_dropped);1154	host_stats->mac_crc_error = le64_to_cpu(ql_iscsi_stats->mac_crc_error);1155	host_stats->mac_encoding_error =1156			le64_to_cpu(ql_iscsi_stats->mac_encoding_error);1157	host_stats->macrx_length_error_large =1158			le64_to_cpu(ql_iscsi_stats->mac_rx_length_error_large);1159	host_stats->macrx_length_error_small =1160			le64_to_cpu(ql_iscsi_stats->mac_rx_length_error_small);1161	host_stats->macrx_multicast_frames =1162			le64_to_cpu(ql_iscsi_stats->mac_rx_multicast_frames);1163	host_stats->macrx_broadcast_frames =1164			le64_to_cpu(ql_iscsi_stats->mac_rx_broadcast_frames);1165	host_stats->iptx_packets = le64_to_cpu(ql_iscsi_stats->ip_tx_packets);1166	host_stats->iptx_bytes = le64_to_cpu(ql_iscsi_stats->ip_tx_bytes);1167	host_stats->iptx_fragments =1168			le64_to_cpu(ql_iscsi_stats->ip_tx_fragments);1169	host_stats->iprx_packets = le64_to_cpu(ql_iscsi_stats->ip_rx_packets);1170	host_stats->iprx_bytes = le64_to_cpu(ql_iscsi_stats->ip_rx_bytes);1171	host_stats->iprx_fragments =1172			le64_to_cpu(ql_iscsi_stats->ip_rx_fragments);1173	host_stats->ip_datagram_reassembly =1174			le64_to_cpu(ql_iscsi_stats->ip_datagram_reassembly);1175	host_stats->ip_invalid_address_error =1176			le64_to_cpu(ql_iscsi_stats->ip_invalid_address_error);1177	host_stats->ip_error_packets =1178			le64_to_cpu(ql_iscsi_stats->ip_error_packets);1179	host_stats->ip_fragrx_overlap =1180			le64_to_cpu(ql_iscsi_stats->ip_fragrx_overlap);1181	host_stats->ip_fragrx_outoforder =1182			le64_to_cpu(ql_iscsi_stats->ip_fragrx_outoforder);1183	host_stats->ip_datagram_reassembly_timeout =1184		le64_to_cpu(ql_iscsi_stats->ip_datagram_reassembly_timeout);1185	host_stats->ipv6tx_packets =1186			le64_to_cpu(ql_iscsi_stats->ipv6_tx_packets);1187	host_stats->ipv6tx_bytes = le64_to_cpu(ql_iscsi_stats->ipv6_tx_bytes);1188	host_stats->ipv6tx_fragments =1189			le64_to_cpu(ql_iscsi_stats->ipv6_tx_fragments);1190	host_stats->ipv6rx_packets =1191			le64_to_cpu(ql_iscsi_stats->ipv6_rx_packets);1192	host_stats->ipv6rx_bytes = le64_to_cpu(ql_iscsi_stats->ipv6_rx_bytes);1193	host_stats->ipv6rx_fragments =1194			le64_to_cpu(ql_iscsi_stats->ipv6_rx_fragments);1195	host_stats->ipv6_datagram_reassembly =1196			le64_to_cpu(ql_iscsi_stats->ipv6_datagram_reassembly);1197	host_stats->ipv6_invalid_address_error =1198		le64_to_cpu(ql_iscsi_stats->ipv6_invalid_address_error);1199	host_stats->ipv6_error_packets =1200			le64_to_cpu(ql_iscsi_stats->ipv6_error_packets);1201	host_stats->ipv6_fragrx_overlap =1202			le64_to_cpu(ql_iscsi_stats->ipv6_fragrx_overlap);1203	host_stats->ipv6_fragrx_outoforder =1204			le64_to_cpu(ql_iscsi_stats->ipv6_fragrx_outoforder);1205	host_stats->ipv6_datagram_reassembly_timeout =1206		le64_to_cpu(ql_iscsi_stats->ipv6_datagram_reassembly_timeout);1207	host_stats->tcptx_segments =1208			le64_to_cpu(ql_iscsi_stats->tcp_tx_segments);1209	host_stats->tcptx_bytes	= le64_to_cpu(ql_iscsi_stats->tcp_tx_bytes);1210	host_stats->tcprx_segments =1211			le64_to_cpu(ql_iscsi_stats->tcp_rx_segments);1212	host_stats->tcprx_byte = le64_to_cpu(ql_iscsi_stats->tcp_rx_byte);1213	host_stats->tcp_duplicate_ack_retx =1214			le64_to_cpu(ql_iscsi_stats->tcp_duplicate_ack_retx);1215	host_stats->tcp_retx_timer_expired =1216			le64_to_cpu(ql_iscsi_stats->tcp_retx_timer_expired);1217	host_stats->tcprx_duplicate_ack	=1218			le64_to_cpu(ql_iscsi_stats->tcp_rx_duplicate_ack);1219	host_stats->tcprx_pure_ackr =1220			le64_to_cpu(ql_iscsi_stats->tcp_rx_pure_ackr);1221	host_stats->tcptx_delayed_ack =1222			le64_to_cpu(ql_iscsi_stats->tcp_tx_delayed_ack);1223	host_stats->tcptx_pure_ack =1224			le64_to_cpu(ql_iscsi_stats->tcp_tx_pure_ack);1225	host_stats->tcprx_segment_error =1226			le64_to_cpu(ql_iscsi_stats->tcp_rx_segment_error);1227	host_stats->tcprx_segment_outoforder =1228			le64_to_cpu(ql_iscsi_stats->tcp_rx_segment_outoforder);1229	host_stats->tcprx_window_probe =1230			le64_to_cpu(ql_iscsi_stats->tcp_rx_window_probe);1231	host_stats->tcprx_window_update =1232			le64_to_cpu(ql_iscsi_stats->tcp_rx_window_update);1233	host_stats->tcptx_window_probe_persist =1234		le64_to_cpu(ql_iscsi_stats->tcp_tx_window_probe_persist);1235	host_stats->ecc_error_correction =1236			le64_to_cpu(ql_iscsi_stats->ecc_error_correction);1237	host_stats->iscsi_pdu_tx = le64_to_cpu(ql_iscsi_stats->iscsi_pdu_tx);1238	host_stats->iscsi_data_bytes_tx =1239			le64_to_cpu(ql_iscsi_stats->iscsi_data_bytes_tx);1240	host_stats->iscsi_pdu_rx = le64_to_cpu(ql_iscsi_stats->iscsi_pdu_rx);1241	host_stats->iscsi_data_bytes_rx	=1242			le64_to_cpu(ql_iscsi_stats->iscsi_data_bytes_rx);1243	host_stats->iscsi_io_completed =1244			le64_to_cpu(ql_iscsi_stats->iscsi_io_completed);1245	host_stats->iscsi_unexpected_io_rx =1246			le64_to_cpu(ql_iscsi_stats->iscsi_unexpected_io_rx);1247	host_stats->iscsi_format_error =1248			le64_to_cpu(ql_iscsi_stats->iscsi_format_error);1249	host_stats->iscsi_hdr_digest_error =1250			le64_to_cpu(ql_iscsi_stats->iscsi_hdr_digest_error);1251	host_stats->iscsi_data_digest_error =1252			le64_to_cpu(ql_iscsi_stats->iscsi_data_digest_error);1253	host_stats->iscsi_sequence_error =1254			le64_to_cpu(ql_iscsi_stats->iscsi_sequence_error);1255exit_host_stats:1256	if (ql_iscsi_stats)1257		dma_free_coherent(&ha->pdev->dev, stats_size,1258				  ql_iscsi_stats, iscsi_stats_dma);1259 1260	ql4_printk(KERN_INFO, ha, "%s: Get host stats done\n",1261		   __func__);1262	return ret;1263}1264 1265static int qla4xxx_get_iface_param(struct iscsi_iface *iface,1266				   enum iscsi_param_type param_type,1267				   int param, char *buf)1268{1269	struct Scsi_Host *shost = iscsi_iface_to_shost(iface);1270	struct scsi_qla_host *ha = to_qla_host(shost);1271	int ival;1272	char *pval = NULL;1273	int len = -ENOSYS;1274 1275	if (param_type == ISCSI_NET_PARAM) {1276		switch (param) {1277		case ISCSI_NET_PARAM_IPV4_ADDR:1278			len = sprintf(buf, "%pI4\n", &ha->ip_config.ip_address);1279			break;1280		case ISCSI_NET_PARAM_IPV4_SUBNET:1281			len = sprintf(buf, "%pI4\n",1282				      &ha->ip_config.subnet_mask);1283			break;1284		case ISCSI_NET_PARAM_IPV4_GW:1285			len = sprintf(buf, "%pI4\n", &ha->ip_config.gateway);1286			break;1287		case ISCSI_NET_PARAM_IFACE_ENABLE:1288			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {1289				OP_STATE(ha->ip_config.ipv4_options,1290					 IPOPT_IPV4_PROTOCOL_ENABLE, pval);1291			} else {1292				OP_STATE(ha->ip_config.ipv6_options,1293					 IPV6_OPT_IPV6_PROTOCOL_ENABLE, pval);1294			}1295 1296			len = sprintf(buf, "%s\n", pval);1297			break;1298		case ISCSI_NET_PARAM_IPV4_BOOTPROTO:1299			len = sprintf(buf, "%s\n",1300				      (ha->ip_config.tcp_options &1301				       TCPOPT_DHCP_ENABLE) ?1302				      "dhcp" : "static");1303			break;1304		case ISCSI_NET_PARAM_IPV6_ADDR:1305			if (iface->iface_num == 0)1306				len = sprintf(buf, "%pI6\n",1307					      &ha->ip_config.ipv6_addr0);1308			if (iface->iface_num == 1)1309				len = sprintf(buf, "%pI6\n",1310					      &ha->ip_config.ipv6_addr1);1311			break;1312		case ISCSI_NET_PARAM_IPV6_LINKLOCAL:1313			len = sprintf(buf, "%pI6\n",1314				      &ha->ip_config.ipv6_link_local_addr);1315			break;1316		case ISCSI_NET_PARAM_IPV6_ROUTER:1317			len = sprintf(buf, "%pI6\n",1318				      &ha->ip_config.ipv6_default_router_addr);1319			break;1320		case ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG:1321			pval = (ha->ip_config.ipv6_addl_options &1322				IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE) ?1323				"nd" : "static";1324 1325			len = sprintf(buf, "%s\n", pval);1326			break;1327		case ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG:1328			pval = (ha->ip_config.ipv6_addl_options &1329				IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR) ?1330				"auto" : "static";1331 1332			len = sprintf(buf, "%s\n", pval);1333			break;1334		case ISCSI_NET_PARAM_VLAN_ID:1335			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)1336				ival = ha->ip_config.ipv4_vlan_tag &1337				       ISCSI_MAX_VLAN_ID;1338			else1339				ival = ha->ip_config.ipv6_vlan_tag &1340				       ISCSI_MAX_VLAN_ID;1341 1342			len = sprintf(buf, "%d\n", ival);1343			break;1344		case ISCSI_NET_PARAM_VLAN_PRIORITY:1345			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)1346				ival = (ha->ip_config.ipv4_vlan_tag >> 13) &1347				       ISCSI_MAX_VLAN_PRIORITY;1348			else1349				ival = (ha->ip_config.ipv6_vlan_tag >> 13) &1350				       ISCSI_MAX_VLAN_PRIORITY;1351 1352			len = sprintf(buf, "%d\n", ival);1353			break;1354		case ISCSI_NET_PARAM_VLAN_ENABLED:1355			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {1356				OP_STATE(ha->ip_config.ipv4_options,1357					 IPOPT_VLAN_TAGGING_ENABLE, pval);1358			} else {1359				OP_STATE(ha->ip_config.ipv6_options,1360					 IPV6_OPT_VLAN_TAGGING_ENABLE, pval);1361			}1362			len = sprintf(buf, "%s\n", pval);1363			break;1364		case ISCSI_NET_PARAM_MTU:1365			len = sprintf(buf, "%d\n", ha->ip_config.eth_mtu_size);1366			break;1367		case ISCSI_NET_PARAM_PORT:1368			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)1369				len = sprintf(buf, "%d\n",1370					      ha->ip_config.ipv4_port);1371			else1372				len = sprintf(buf, "%d\n",1373					      ha->ip_config.ipv6_port);1374			break;1375		case ISCSI_NET_PARAM_IPADDR_STATE:1376			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {1377				pval = iscsi_get_ipaddress_state_name(1378						ha->ip_config.ipv4_addr_state);1379			} else {1380				if (iface->iface_num == 0)1381					pval = iscsi_get_ipaddress_state_name(1382						ha->ip_config.ipv6_addr0_state);1383				else if (iface->iface_num == 1)1384					pval = iscsi_get_ipaddress_state_name(1385						ha->ip_config.ipv6_addr1_state);1386			}1387 1388			len = sprintf(buf, "%s\n", pval);1389			break;1390		case ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE:1391			pval = iscsi_get_ipaddress_state_name(1392					ha->ip_config.ipv6_link_local_state);1393			len = sprintf(buf, "%s\n", pval);1394			break;1395		case ISCSI_NET_PARAM_IPV6_ROUTER_STATE:1396			pval = iscsi_get_router_state_name(1397				      ha->ip_config.ipv6_default_router_state);1398			len = sprintf(buf, "%s\n", pval);1399			break;1400		case ISCSI_NET_PARAM_DELAYED_ACK_EN:1401			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {1402				OP_STATE(~ha->ip_config.tcp_options,1403					 TCPOPT_DELAYED_ACK_DISABLE, pval);1404			} else {1405				OP_STATE(~ha->ip_config.ipv6_tcp_options,1406					 IPV6_TCPOPT_DELAYED_ACK_DISABLE, pval);1407			}1408			len = sprintf(buf, "%s\n", pval);1409			break;1410		case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE:1411			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {1412				OP_STATE(~ha->ip_config.tcp_options,1413					 TCPOPT_NAGLE_ALGO_DISABLE, pval);1414			} else {1415				OP_STATE(~ha->ip_config.ipv6_tcp_options,1416					 IPV6_TCPOPT_NAGLE_ALGO_DISABLE, pval);1417			}1418			len = sprintf(buf, "%s\n", pval);1419			break;1420		case ISCSI_NET_PARAM_TCP_WSF_DISABLE:1421			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {1422				OP_STATE(~ha->ip_config.tcp_options,1423					 TCPOPT_WINDOW_SCALE_DISABLE, pval);1424			} else {1425				OP_STATE(~ha->ip_config.ipv6_tcp_options,1426					 IPV6_TCPOPT_WINDOW_SCALE_DISABLE,1427					 pval);1428			}1429			len = sprintf(buf, "%s\n", pval);1430			break;1431		case ISCSI_NET_PARAM_TCP_WSF:1432			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)1433				len = sprintf(buf, "%d\n",1434					      ha->ip_config.tcp_wsf);1435			else1436				len = sprintf(buf, "%d\n",1437					      ha->ip_config.ipv6_tcp_wsf);1438			break;1439		case ISCSI_NET_PARAM_TCP_TIMER_SCALE:1440			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)1441				ival = (ha->ip_config.tcp_options &1442					TCPOPT_TIMER_SCALE) >> 1;1443			else1444				ival = (ha->ip_config.ipv6_tcp_options &1445					IPV6_TCPOPT_TIMER_SCALE) >> 1;1446 1447			len = sprintf(buf, "%d\n", ival);1448			break;1449		case ISCSI_NET_PARAM_TCP_TIMESTAMP_EN:1450			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {1451				OP_STATE(ha->ip_config.tcp_options,1452					 TCPOPT_TIMESTAMP_ENABLE, pval);1453			} else {1454				OP_STATE(ha->ip_config.ipv6_tcp_options,1455					 IPV6_TCPOPT_TIMESTAMP_EN, pval);1456			}1457			len = sprintf(buf, "%s\n", pval);1458			break;1459		case ISCSI_NET_PARAM_CACHE_ID:1460			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4)1461				len = sprintf(buf, "%d\n",1462					      ha->ip_config.ipv4_cache_id);1463			else1464				len = sprintf(buf, "%d\n",1465					      ha->ip_config.ipv6_cache_id);1466			break;1467		case ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN:1468			OP_STATE(ha->ip_config.tcp_options,1469				 TCPOPT_DNS_SERVER_IP_EN, pval);1470 1471			len = sprintf(buf, "%s\n", pval);1472			break;1473		case ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN:1474			OP_STATE(ha->ip_config.tcp_options,1475				 TCPOPT_SLP_DA_INFO_EN, pval);1476 1477			len = sprintf(buf, "%s\n", pval);1478			break;1479		case ISCSI_NET_PARAM_IPV4_TOS_EN:1480			OP_STATE(ha->ip_config.ipv4_options,1481				 IPOPT_IPV4_TOS_EN, pval);1482 1483			len = sprintf(buf, "%s\n", pval);1484			break;1485		case ISCSI_NET_PARAM_IPV4_TOS:1486			len = sprintf(buf, "%d\n", ha->ip_config.ipv4_tos);1487			break;1488		case ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN:1489			OP_STATE(ha->ip_config.ipv4_options,1490				 IPOPT_GRAT_ARP_EN, pval);1491 1492			len = sprintf(buf, "%s\n", pval);1493			break;1494		case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN:1495			OP_STATE(ha->ip_config.ipv4_options, IPOPT_ALT_CID_EN,1496				 pval);1497 1498			len = sprintf(buf, "%s\n", pval);1499			break;1500		case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID:1501			pval = (ha->ip_config.ipv4_alt_cid_len) ?1502			       (char *)ha->ip_config.ipv4_alt_cid : "";1503 1504			len = sprintf(buf, "%s\n", pval);1505			break;1506		case ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN:1507			OP_STATE(ha->ip_config.ipv4_options,1508				 IPOPT_REQ_VID_EN, pval);1509 1510			len = sprintf(buf, "%s\n", pval);1511			break;1512		case ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN:1513			OP_STATE(ha->ip_config.ipv4_options,1514				 IPOPT_USE_VID_EN, pval);1515 1516			len = sprintf(buf, "%s\n", pval);1517			break;1518		case ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID:1519			pval = (ha->ip_config.ipv4_vid_len) ?1520			       (char *)ha->ip_config.ipv4_vid : "";1521 1522			len = sprintf(buf, "%s\n", pval);1523			break;1524		case ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN:1525			OP_STATE(ha->ip_config.ipv4_options,1526				 IPOPT_LEARN_IQN_EN, pval);1527 1528			len = sprintf(buf, "%s\n", pval);1529			break;1530		case ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE:1531			OP_STATE(~ha->ip_config.ipv4_options,1532				 IPOPT_FRAGMENTATION_DISABLE, pval);1533 1534			len = sprintf(buf, "%s\n", pval);1535			break;1536		case ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN:1537			OP_STATE(ha->ip_config.ipv4_options,1538				 IPOPT_IN_FORWARD_EN, pval);1539 1540			len = sprintf(buf, "%s\n", pval);1541			break;1542		case ISCSI_NET_PARAM_REDIRECT_EN:1543			if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) {1544				OP_STATE(ha->ip_config.ipv4_options,1545					 IPOPT_ARP_REDIRECT_EN, pval);1546			} else {1547				OP_STATE(ha->ip_config.ipv6_options,1548					 IPV6_OPT_REDIRECT_EN, pval);1549			}1550			len = sprintf(buf, "%s\n", pval);1551			break;1552		case ISCSI_NET_PARAM_IPV4_TTL:1553			len = sprintf(buf, "%d\n", ha->ip_config.ipv4_ttl);1554			break;1555		case ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN:1556			OP_STATE(ha->ip_config.ipv6_options,1557				 IPV6_OPT_GRAT_NEIGHBOR_ADV_EN, pval);1558 1559			len = sprintf(buf, "%s\n", pval);1560			break;1561		case ISCSI_NET_PARAM_IPV6_MLD_EN:1562			OP_STATE(ha->ip_config.ipv6_addl_options,1563				 IPV6_ADDOPT_MLD_EN, pval);1564 1565			len = sprintf(buf, "%s\n", pval);1566			break;1567		case ISCSI_NET_PARAM_IPV6_FLOW_LABEL:1568			len = sprintf(buf, "%u\n", ha->ip_config.ipv6_flow_lbl);1569			break;1570		case ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS:1571			len = sprintf(buf, "%d\n",1572				      ha->ip_config.ipv6_traffic_class);1573			break;1574		case ISCSI_NET_PARAM_IPV6_HOP_LIMIT:1575			len = sprintf(buf, "%d\n",1576				      ha->ip_config.ipv6_hop_limit);1577			break;1578		case ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO:1579			len = sprintf(buf, "%d\n",1580				      ha->ip_config.ipv6_nd_reach_time);1581			break;1582		case ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME:1583			len = sprintf(buf, "%d\n",1584				      ha->ip_config.ipv6_nd_rexmit_timer);1585			break;1586		case ISCSI_NET_PARAM_IPV6_ND_STALE_TMO:1587			len = sprintf(buf, "%d\n",1588				      ha->ip_config.ipv6_nd_stale_timeout);1589			break;1590		case ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT:1591			len = sprintf(buf, "%d\n",1592				      ha->ip_config.ipv6_dup_addr_detect_count);1593			break;1594		case ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU:1595			len = sprintf(buf, "%d\n",1596				      ha->ip_config.ipv6_gw_advrt_mtu);1597			break;1598		default:1599			len = -ENOSYS;1600		}1601	} else if (param_type == ISCSI_IFACE_PARAM) {1602		switch (param) {1603		case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO:1604			len = sprintf(buf, "%d\n", ha->ip_config.def_timeout);1605			break;1606		case ISCSI_IFACE_PARAM_HDRDGST_EN:1607			OP_STATE(ha->ip_config.iscsi_options,1608				 ISCSIOPTS_HEADER_DIGEST_EN, pval);1609 1610			len = sprintf(buf, "%s\n", pval);1611			break;1612		case ISCSI_IFACE_PARAM_DATADGST_EN:1613			OP_STATE(ha->ip_config.iscsi_options,1614				 ISCSIOPTS_DATA_DIGEST_EN, pval);1615 1616			len = sprintf(buf, "%s\n", pval);1617			break;1618		case ISCSI_IFACE_PARAM_IMM_DATA_EN:1619			OP_STATE(ha->ip_config.iscsi_options,1620				 ISCSIOPTS_IMMEDIATE_DATA_EN, pval);1621 1622			len = sprintf(buf, "%s\n", pval);1623			break;1624		case ISCSI_IFACE_PARAM_INITIAL_R2T_EN:1625			OP_STATE(ha->ip_config.iscsi_options,1626				 ISCSIOPTS_INITIAL_R2T_EN, pval);1627 1628			len = sprintf(buf, "%s\n", pval);1629			break;1630		case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN:1631			OP_STATE(ha->ip_config.iscsi_options,1632				 ISCSIOPTS_DATA_SEQ_INORDER_EN, pval);1633 1634			len = sprintf(buf, "%s\n", pval);1635			break;1636		case ISCSI_IFACE_PARAM_PDU_INORDER_EN:1637			OP_STATE(ha->ip_config.iscsi_options,1638				 ISCSIOPTS_DATA_PDU_INORDER_EN, pval);1639 1640			len = sprintf(buf, "%s\n", pval);1641			break;1642		case ISCSI_IFACE_PARAM_ERL:1643			len = sprintf(buf, "%d\n",1644				      (ha->ip_config.iscsi_options &1645				       ISCSIOPTS_ERL));1646			break;1647		case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH:1648			len = sprintf(buf, "%u\n",1649				      ha->ip_config.iscsi_max_pdu_size *1650				      BYTE_UNITS);1651			break;1652		case ISCSI_IFACE_PARAM_FIRST_BURST:1653			len = sprintf(buf, "%u\n",1654				      ha->ip_config.iscsi_first_burst_len *1655				      BYTE_UNITS);1656			break;1657		case ISCSI_IFACE_PARAM_MAX_R2T:1658			len = sprintf(buf, "%d\n",1659				      ha->ip_config.iscsi_max_outstnd_r2t);1660			break;1661		case ISCSI_IFACE_PARAM_MAX_BURST:1662			len = sprintf(buf, "%u\n",1663				      ha->ip_config.iscsi_max_burst_len *1664				      BYTE_UNITS);1665			break;1666		case ISCSI_IFACE_PARAM_CHAP_AUTH_EN:1667			OP_STATE(ha->ip_config.iscsi_options,1668				 ISCSIOPTS_CHAP_AUTH_EN, pval);1669 1670			len = sprintf(buf, "%s\n", pval);1671			break;1672		case ISCSI_IFACE_PARAM_BIDI_CHAP_EN:1673			OP_STATE(ha->ip_config.iscsi_options,1674				 ISCSIOPTS_BIDI_CHAP_EN, pval);1675 1676			len = sprintf(buf, "%s\n", pval);1677			break;1678		case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL:1679			OP_STATE(ha->ip_config.iscsi_options,1680				 ISCSIOPTS_DISCOVERY_AUTH_EN, pval);1681 1682			len = sprintf(buf, "%s\n", pval);1683			break;1684		case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN:1685			OP_STATE(ha->ip_config.iscsi_options,1686				 ISCSIOPTS_DISCOVERY_LOGOUT_EN, pval);1687 1688			len = sprintf(buf, "%s\n", pval);1689			break;1690		case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN:1691			OP_STATE(ha->ip_config.iscsi_options,1692				 ISCSIOPTS_STRICT_LOGIN_COMP_EN, pval);1693 1694			len = sprintf(buf, "%s\n", pval);1695			break;1696		case ISCSI_IFACE_PARAM_INITIATOR_NAME:1697			len = sprintf(buf, "%s\n", ha->ip_config.iscsi_name);1698			break;1699		default:1700			len = -ENOSYS;1701		}1702	}1703 1704	return len;1705}1706 1707static struct iscsi_endpoint *1708qla4xxx_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,1709		   int non_blocking)1710{1711	int ret;1712	struct iscsi_endpoint *ep;1713	struct qla_endpoint *qla_ep;1714	struct scsi_qla_host *ha;1715	struct sockaddr_in *addr;1716	struct sockaddr_in6 *addr6;1717 1718	if (!shost) {1719		ret = -ENXIO;1720		pr_err("%s: shost is NULL\n", __func__);1721		return ERR_PTR(ret);1722	}1723 1724	ha = iscsi_host_priv(shost);1725	ep = iscsi_create_endpoint(sizeof(struct qla_endpoint));1726	if (!ep) {1727		ret = -ENOMEM;1728		return ERR_PTR(ret);1729	}1730 1731	qla_ep = ep->dd_data;1732	memset(qla_ep, 0, sizeof(struct qla_endpoint));1733	if (dst_addr->sa_family == AF_INET) {1734		memcpy(&qla_ep->dst_addr, dst_addr, sizeof(struct sockaddr_in));1735		addr = (struct sockaddr_in *)&qla_ep->dst_addr;1736		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: %pI4\n", __func__,1737				  (char *)&addr->sin_addr));1738	} else if (dst_addr->sa_family == AF_INET6) {1739		memcpy(&qla_ep->dst_addr, dst_addr,1740		       sizeof(struct sockaddr_in6));1741		addr6 = (struct sockaddr_in6 *)&qla_ep->dst_addr;1742		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: %pI6\n", __func__,1743				  (char *)&addr6->sin6_addr));1744	} else {1745		ql4_printk(KERN_WARNING, ha, "%s: Invalid endpoint\n",1746			   __func__);1747	}1748 1749	qla_ep->host = shost;1750 1751	return ep;1752}1753 1754static int qla4xxx_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)1755{1756	struct qla_endpoint *qla_ep;1757	struct scsi_qla_host *ha;1758	int ret = 0;1759 1760	qla_ep = ep->dd_data;1761	ha = to_qla_host(qla_ep->host);1762	DEBUG2(pr_info_ratelimited("%s: host: %ld\n", __func__, ha->host_no));1763 1764	if (adapter_up(ha) && !test_bit(AF_BUILD_DDB_LIST, &ha->flags))1765		ret = 1;1766 1767	return ret;1768}1769 1770static void qla4xxx_ep_disconnect(struct iscsi_endpoint *ep)1771{1772	struct qla_endpoint *qla_ep;1773	struct scsi_qla_host *ha;1774 1775	qla_ep = ep->dd_data;1776	ha = to_qla_host(qla_ep->host);1777	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: host: %ld\n", __func__,1778			  ha->host_no));1779	iscsi_destroy_endpoint(ep);1780}1781 1782static int qla4xxx_get_ep_param(struct iscsi_endpoint *ep,1783				enum iscsi_param param,1784				char *buf)1785{1786	struct qla_endpoint *qla_ep = ep->dd_data;1787	struct sockaddr *dst_addr;1788	struct scsi_qla_host *ha;1789 1790	if (!qla_ep)1791		return -ENOTCONN;1792 1793	ha = to_qla_host(qla_ep->host);1794	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: host: %ld\n", __func__,1795			  ha->host_no));1796 1797	switch (param) {1798	case ISCSI_PARAM_CONN_PORT:1799	case ISCSI_PARAM_CONN_ADDRESS:1800		dst_addr = (struct sockaddr *)&qla_ep->dst_addr;1801		if (!dst_addr)1802			return -ENOTCONN;1803 1804		return iscsi_conn_get_addr_param((struct sockaddr_storage *)1805						 &qla_ep->dst_addr, param, buf);1806	default:1807		return -ENOSYS;1808	}1809}1810 1811static void qla4xxx_conn_get_stats(struct iscsi_cls_conn *cls_conn,1812				   struct iscsi_stats *stats)1813{1814	struct iscsi_session *sess;1815	struct iscsi_cls_session *cls_sess;1816	struct ddb_entry *ddb_entry;1817	struct scsi_qla_host *ha;1818	struct ql_iscsi_stats *ql_iscsi_stats;1819	int stats_size;1820	int ret;1821	dma_addr_t iscsi_stats_dma;1822 1823	cls_sess = iscsi_conn_to_session(cls_conn);1824	sess = cls_sess->dd_data;1825	ddb_entry = sess->dd_data;1826	ha = ddb_entry->ha;1827 1828	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: host: %ld\n", __func__,1829			  ha->host_no));1830	stats_size = PAGE_ALIGN(sizeof(struct ql_iscsi_stats));1831	/* Allocate memory */1832	ql_iscsi_stats = dma_alloc_coherent(&ha->pdev->dev, stats_size,1833					    &iscsi_stats_dma, GFP_KERNEL);1834	if (!ql_iscsi_stats) {1835		ql4_printk(KERN_ERR, ha,1836			   "Unable to allocate memory for iscsi stats\n");1837		goto exit_get_stats;1838	}1839 1840	ret =  qla4xxx_get_mgmt_data(ha, ddb_entry->fw_ddb_index, stats_size,1841				     iscsi_stats_dma);1842	if (ret != QLA_SUCCESS) {1843		ql4_printk(KERN_ERR, ha,1844			   "Unable to retrieve iscsi stats\n");1845		goto free_stats;1846	}1847 1848	/* octets */1849	stats->txdata_octets = le64_to_cpu(ql_iscsi_stats->tx_data_octets);1850	stats->rxdata_octets = le64_to_cpu(ql_iscsi_stats->rx_data_octets);1851	/* xmit pdus */1852	stats->noptx_pdus = le32_to_cpu(ql_iscsi_stats->tx_nopout_pdus);1853	stats->scsicmd_pdus = le32_to_cpu(ql_iscsi_stats->tx_scsi_cmd_pdus);1854	stats->tmfcmd_pdus = le32_to_cpu(ql_iscsi_stats->tx_tmf_cmd_pdus);1855	stats->login_pdus = le32_to_cpu(ql_iscsi_stats->tx_login_cmd_pdus);1856	stats->text_pdus = le32_to_cpu(ql_iscsi_stats->tx_text_cmd_pdus);1857	stats->dataout_pdus = le32_to_cpu(ql_iscsi_stats->tx_scsi_write_pdus);1858	stats->logout_pdus = le32_to_cpu(ql_iscsi_stats->tx_logout_cmd_pdus);1859	stats->snack_pdus = le32_to_cpu(ql_iscsi_stats->tx_snack_req_pdus);1860	/* recv pdus */1861	stats->noprx_pdus = le32_to_cpu(ql_iscsi_stats->rx_nopin_pdus);1862	stats->scsirsp_pdus = le32_to_cpu(ql_iscsi_stats->rx_scsi_resp_pdus);1863	stats->tmfrsp_pdus = le32_to_cpu(ql_iscsi_stats->rx_tmf_resp_pdus);1864	stats->textrsp_pdus = le32_to_cpu(ql_iscsi_stats->rx_text_resp_pdus);1865	stats->datain_pdus = le32_to_cpu(ql_iscsi_stats->rx_scsi_read_pdus);1866	stats->logoutrsp_pdus =1867			le32_to_cpu(ql_iscsi_stats->rx_logout_resp_pdus);1868	stats->r2t_pdus = le32_to_cpu(ql_iscsi_stats->rx_r2t_pdus);1869	stats->async_pdus = le32_to_cpu(ql_iscsi_stats->rx_async_pdus);1870	stats->rjt_pdus = le32_to_cpu(ql_iscsi_stats->rx_reject_pdus);1871 1872free_stats:1873	dma_free_coherent(&ha->pdev->dev, stats_size, ql_iscsi_stats,1874			  iscsi_stats_dma);1875exit_get_stats:1876	return;1877}1878 1879static enum scsi_timeout_action qla4xxx_eh_cmd_timed_out(struct scsi_cmnd *sc)1880{1881	struct iscsi_cls_session *session;1882	unsigned long flags;1883	enum scsi_timeout_action ret = SCSI_EH_NOT_HANDLED;1884 1885	session = starget_to_session(scsi_target(sc->device));1886 1887	spin_lock_irqsave(&session->lock, flags);1888	if (session->state == ISCSI_SESSION_FAILED)1889		ret = SCSI_EH_RESET_TIMER;1890	spin_unlock_irqrestore(&session->lock, flags);1891 1892	return ret;1893}1894 1895static void qla4xxx_set_port_speed(struct Scsi_Host *shost)1896{1897	struct scsi_qla_host *ha = to_qla_host(shost);1898	struct iscsi_cls_host *ihost = shost->shost_data;1899	uint32_t speed = ISCSI_PORT_SPEED_UNKNOWN;1900 1901	qla4xxx_get_firmware_state(ha);1902 1903	switch (ha->addl_fw_state & 0x0F00) {1904	case FW_ADDSTATE_LINK_SPEED_10MBPS:1905		speed = ISCSI_PORT_SPEED_10MBPS;1906		break;1907	case FW_ADDSTATE_LINK_SPEED_100MBPS:1908		speed = ISCSI_PORT_SPEED_100MBPS;1909		break;1910	case FW_ADDSTATE_LINK_SPEED_1GBPS:1911		speed = ISCSI_PORT_SPEED_1GBPS;1912		break;1913	case FW_ADDSTATE_LINK_SPEED_10GBPS:1914		speed = ISCSI_PORT_SPEED_10GBPS;1915		break;1916	}1917	ihost->port_speed = speed;1918}1919 1920static void qla4xxx_set_port_state(struct Scsi_Host *shost)1921{1922	struct scsi_qla_host *ha = to_qla_host(shost);1923	struct iscsi_cls_host *ihost = shost->shost_data;1924	uint32_t state = ISCSI_PORT_STATE_DOWN;1925 1926	if (test_bit(AF_LINK_UP, &ha->flags))1927		state = ISCSI_PORT_STATE_UP;1928 1929	ihost->port_state = state;1930}1931 1932static int qla4xxx_host_get_param(struct Scsi_Host *shost,1933				  enum iscsi_host_param param, char *buf)1934{1935	struct scsi_qla_host *ha = to_qla_host(shost);1936	int len;1937 1938	switch (param) {1939	case ISCSI_HOST_PARAM_HWADDRESS:1940		len = sysfs_format_mac(buf, ha->my_mac, MAC_ADDR_LEN);1941		break;1942	case ISCSI_HOST_PARAM_IPADDRESS:1943		len = sprintf(buf, "%pI4\n", &ha->ip_config.ip_address);1944		break;1945	case ISCSI_HOST_PARAM_INITIATOR_NAME:1946		len = sprintf(buf, "%s\n", ha->name_string);1947		break;1948	case ISCSI_HOST_PARAM_PORT_STATE:1949		qla4xxx_set_port_state(shost);1950		len = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost));1951		break;1952	case ISCSI_HOST_PARAM_PORT_SPEED:1953		qla4xxx_set_port_speed(shost);1954		len = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost));1955		break;1956	default:1957		return -ENOSYS;1958	}1959 1960	return len;1961}1962 1963static void qla4xxx_create_ipv4_iface(struct scsi_qla_host *ha)1964{1965	if (ha->iface_ipv4)1966		return;1967 1968	/* IPv4 */1969	ha->iface_ipv4 = iscsi_create_iface(ha->host,1970					    &qla4xxx_iscsi_transport,1971					    ISCSI_IFACE_TYPE_IPV4, 0, 0);1972	if (!ha->iface_ipv4)1973		ql4_printk(KERN_ERR, ha, "Could not create IPv4 iSCSI "1974			   "iface0.\n");1975}1976 1977static void qla4xxx_create_ipv6_iface(struct scsi_qla_host *ha)1978{1979	if (!ha->iface_ipv6_0)1980		/* IPv6 iface-0 */1981		ha->iface_ipv6_0 = iscsi_create_iface(ha->host,1982						      &qla4xxx_iscsi_transport,1983						      ISCSI_IFACE_TYPE_IPV6, 0,1984						      0);1985	if (!ha->iface_ipv6_0)1986		ql4_printk(KERN_ERR, ha, "Could not create IPv6 iSCSI "1987			   "iface0.\n");1988 1989	if (!ha->iface_ipv6_1)1990		/* IPv6 iface-1 */1991		ha->iface_ipv6_1 = iscsi_create_iface(ha->host,1992						      &qla4xxx_iscsi_transport,1993						      ISCSI_IFACE_TYPE_IPV6, 1,1994						      0);1995	if (!ha->iface_ipv6_1)1996		ql4_printk(KERN_ERR, ha, "Could not create IPv6 iSCSI "1997			   "iface1.\n");1998}1999 2000static void qla4xxx_create_ifaces(struct scsi_qla_host *ha)2001{2002	if (ha->ip_config.ipv4_options & IPOPT_IPV4_PROTOCOL_ENABLE)2003		qla4xxx_create_ipv4_iface(ha);2004 2005	if (ha->ip_config.ipv6_options & IPV6_OPT_IPV6_PROTOCOL_ENABLE)2006		qla4xxx_create_ipv6_iface(ha);2007}2008 2009static void qla4xxx_destroy_ipv4_iface(struct scsi_qla_host *ha)2010{2011	if (ha->iface_ipv4) {2012		iscsi_destroy_iface(ha->iface_ipv4);2013		ha->iface_ipv4 = NULL;2014	}2015}2016 2017static void qla4xxx_destroy_ipv6_iface(struct scsi_qla_host *ha)2018{2019	if (ha->iface_ipv6_0) {2020		iscsi_destroy_iface(ha->iface_ipv6_0);2021		ha->iface_ipv6_0 = NULL;2022	}2023	if (ha->iface_ipv6_1) {2024		iscsi_destroy_iface(ha->iface_ipv6_1);2025		ha->iface_ipv6_1 = NULL;2026	}2027}2028 2029static void qla4xxx_destroy_ifaces(struct scsi_qla_host *ha)2030{2031	qla4xxx_destroy_ipv4_iface(ha);2032	qla4xxx_destroy_ipv6_iface(ha);2033}2034 2035static void qla4xxx_set_ipv6(struct scsi_qla_host *ha,2036			     struct iscsi_iface_param_info *iface_param,2037			     struct addr_ctrl_blk *init_fw_cb)2038{2039	/*2040	 * iface_num 0 is valid for IPv6 Addr, linklocal, router, autocfg.2041	 * iface_num 1 is valid only for IPv6 Addr.2042	 */2043	switch (iface_param->param) {2044	case ISCSI_NET_PARAM_IPV6_ADDR:2045		if (iface_param->iface_num & 0x1)2046			/* IPv6 Addr 1 */2047			memcpy(init_fw_cb->ipv6_addr1, iface_param->value,2048			       sizeof(init_fw_cb->ipv6_addr1));2049		else2050			/* IPv6 Addr 0 */2051			memcpy(init_fw_cb->ipv6_addr0, iface_param->value,2052			       sizeof(init_fw_cb->ipv6_addr0));2053		break;2054	case ISCSI_NET_PARAM_IPV6_LINKLOCAL:2055		if (iface_param->iface_num & 0x1)2056			break;2057		memcpy(init_fw_cb->ipv6_if_id, &iface_param->value[8],2058		       sizeof(init_fw_cb->ipv6_if_id));2059		break;2060	case ISCSI_NET_PARAM_IPV6_ROUTER:2061		if (iface_param->iface_num & 0x1)2062			break;2063		memcpy(init_fw_cb->ipv6_dflt_rtr_addr, iface_param->value,2064		       sizeof(init_fw_cb->ipv6_dflt_rtr_addr));2065		break;2066	case ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG:2067		/* Autocfg applies to even interface */2068		if (iface_param->iface_num & 0x1)2069			break;2070 2071		if (iface_param->value[0] == ISCSI_IPV6_AUTOCFG_DISABLE)2072			init_fw_cb->ipv6_addtl_opts &=2073				cpu_to_le16(2074				  ~IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE);2075		else if (iface_param->value[0] == ISCSI_IPV6_AUTOCFG_ND_ENABLE)2076			init_fw_cb->ipv6_addtl_opts |=2077				cpu_to_le16(2078				  IPV6_ADDOPT_NEIGHBOR_DISCOVERY_ADDR_ENABLE);2079		else2080			ql4_printk(KERN_ERR, ha,2081				   "Invalid autocfg setting for IPv6 addr\n");2082		break;2083	case ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG:2084		/* Autocfg applies to even interface */2085		if (iface_param->iface_num & 0x1)2086			break;2087 2088		if (iface_param->value[0] ==2089		    ISCSI_IPV6_LINKLOCAL_AUTOCFG_ENABLE)2090			init_fw_cb->ipv6_addtl_opts |= cpu_to_le16(2091					IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR);2092		else if (iface_param->value[0] ==2093			 ISCSI_IPV6_LINKLOCAL_AUTOCFG_DISABLE)2094			init_fw_cb->ipv6_addtl_opts &= cpu_to_le16(2095				       ~IPV6_ADDOPT_AUTOCONFIG_LINK_LOCAL_ADDR);2096		else2097			ql4_printk(KERN_ERR, ha,2098				   "Invalid autocfg setting for IPv6 linklocal addr\n");2099		break;2100	case ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG:2101		/* Autocfg applies to even interface */2102		if (iface_param->iface_num & 0x1)2103			break;2104 2105		if (iface_param->value[0] == ISCSI_IPV6_ROUTER_AUTOCFG_ENABLE)2106			memset(init_fw_cb->ipv6_dflt_rtr_addr, 0,2107			       sizeof(init_fw_cb->ipv6_dflt_rtr_addr));2108		break;2109	case ISCSI_NET_PARAM_IFACE_ENABLE:2110		if (iface_param->value[0] == ISCSI_IFACE_ENABLE) {2111			init_fw_cb->ipv6_opts |=2112				cpu_to_le16(IPV6_OPT_IPV6_PROTOCOL_ENABLE);2113			qla4xxx_create_ipv6_iface(ha);2114		} else {2115			init_fw_cb->ipv6_opts &=2116				cpu_to_le16(~IPV6_OPT_IPV6_PROTOCOL_ENABLE &2117					    0xFFFF);2118			qla4xxx_destroy_ipv6_iface(ha);2119		}2120		break;2121	case ISCSI_NET_PARAM_VLAN_TAG:2122		if (iface_param->len != sizeof(init_fw_cb->ipv6_vlan_tag))2123			break;2124		init_fw_cb->ipv6_vlan_tag =2125				cpu_to_be16(*(uint16_t *)iface_param->value);2126		break;2127	case ISCSI_NET_PARAM_VLAN_ENABLED:2128		if (iface_param->value[0] == ISCSI_VLAN_ENABLE)2129			init_fw_cb->ipv6_opts |=2130				cpu_to_le16(IPV6_OPT_VLAN_TAGGING_ENABLE);2131		else2132			init_fw_cb->ipv6_opts &=2133				cpu_to_le16(~IPV6_OPT_VLAN_TAGGING_ENABLE);2134		break;2135	case ISCSI_NET_PARAM_MTU:2136		init_fw_cb->eth_mtu_size =2137				cpu_to_le16(*(uint16_t *)iface_param->value);2138		break;2139	case ISCSI_NET_PARAM_PORT:2140		/* Autocfg applies to even interface */2141		if (iface_param->iface_num & 0x1)2142			break;2143 2144		init_fw_cb->ipv6_port =2145				cpu_to_le16(*(uint16_t *)iface_param->value);2146		break;2147	case ISCSI_NET_PARAM_DELAYED_ACK_EN:2148		if (iface_param->iface_num & 0x1)2149			break;2150		if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)2151			init_fw_cb->ipv6_tcp_opts |=2152				cpu_to_le16(IPV6_TCPOPT_DELAYED_ACK_DISABLE);2153		else2154			init_fw_cb->ipv6_tcp_opts &=2155				cpu_to_le16(~IPV6_TCPOPT_DELAYED_ACK_DISABLE &2156					    0xFFFF);2157		break;2158	case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE:2159		if (iface_param->iface_num & 0x1)2160			break;2161		if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)2162			init_fw_cb->ipv6_tcp_opts |=2163				cpu_to_le16(IPV6_TCPOPT_NAGLE_ALGO_DISABLE);2164		else2165			init_fw_cb->ipv6_tcp_opts &=2166				cpu_to_le16(~IPV6_TCPOPT_NAGLE_ALGO_DISABLE);2167		break;2168	case ISCSI_NET_PARAM_TCP_WSF_DISABLE:2169		if (iface_param->iface_num & 0x1)2170			break;2171		if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)2172			init_fw_cb->ipv6_tcp_opts |=2173				cpu_to_le16(IPV6_TCPOPT_WINDOW_SCALE_DISABLE);2174		else2175			init_fw_cb->ipv6_tcp_opts &=2176				cpu_to_le16(~IPV6_TCPOPT_WINDOW_SCALE_DISABLE);2177		break;2178	case ISCSI_NET_PARAM_TCP_WSF:2179		if (iface_param->iface_num & 0x1)2180			break;2181		init_fw_cb->ipv6_tcp_wsf = iface_param->value[0];2182		break;2183	case ISCSI_NET_PARAM_TCP_TIMER_SCALE:2184		if (iface_param->iface_num & 0x1)2185			break;2186		init_fw_cb->ipv6_tcp_opts &=2187					cpu_to_le16(~IPV6_TCPOPT_TIMER_SCALE);2188		init_fw_cb->ipv6_tcp_opts |=2189				cpu_to_le16((iface_param->value[0] << 1) &2190					    IPV6_TCPOPT_TIMER_SCALE);2191		break;2192	case ISCSI_NET_PARAM_TCP_TIMESTAMP_EN:2193		if (iface_param->iface_num & 0x1)2194			break;2195		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2196			init_fw_cb->ipv6_tcp_opts |=2197				cpu_to_le16(IPV6_TCPOPT_TIMESTAMP_EN);2198		else2199			init_fw_cb->ipv6_tcp_opts &=2200				cpu_to_le16(~IPV6_TCPOPT_TIMESTAMP_EN);2201		break;2202	case ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN:2203		if (iface_param->iface_num & 0x1)2204			break;2205		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2206			init_fw_cb->ipv6_opts |=2207				cpu_to_le16(IPV6_OPT_GRAT_NEIGHBOR_ADV_EN);2208		else2209			init_fw_cb->ipv6_opts &=2210				cpu_to_le16(~IPV6_OPT_GRAT_NEIGHBOR_ADV_EN);2211		break;2212	case ISCSI_NET_PARAM_REDIRECT_EN:2213		if (iface_param->iface_num & 0x1)2214			break;2215		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2216			init_fw_cb->ipv6_opts |=2217				cpu_to_le16(IPV6_OPT_REDIRECT_EN);2218		else2219			init_fw_cb->ipv6_opts &=2220				cpu_to_le16(~IPV6_OPT_REDIRECT_EN);2221		break;2222	case ISCSI_NET_PARAM_IPV6_MLD_EN:2223		if (iface_param->iface_num & 0x1)2224			break;2225		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2226			init_fw_cb->ipv6_addtl_opts |=2227				cpu_to_le16(IPV6_ADDOPT_MLD_EN);2228		else2229			init_fw_cb->ipv6_addtl_opts &=2230				cpu_to_le16(~IPV6_ADDOPT_MLD_EN);2231		break;2232	case ISCSI_NET_PARAM_IPV6_FLOW_LABEL:2233		if (iface_param->iface_num & 0x1)2234			break;2235		init_fw_cb->ipv6_flow_lbl =2236				cpu_to_le16(*(uint16_t *)iface_param->value);2237		break;2238	case ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS:2239		if (iface_param->iface_num & 0x1)2240			break;2241		init_fw_cb->ipv6_traffic_class = iface_param->value[0];2242		break;2243	case ISCSI_NET_PARAM_IPV6_HOP_LIMIT:2244		if (iface_param->iface_num & 0x1)2245			break;2246		init_fw_cb->ipv6_hop_limit = iface_param->value[0];2247		break;2248	case ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO:2249		if (iface_param->iface_num & 0x1)2250			break;2251		init_fw_cb->ipv6_nd_reach_time =2252				cpu_to_le32(*(uint32_t *)iface_param->value);2253		break;2254	case ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME:2255		if (iface_param->iface_num & 0x1)2256			break;2257		init_fw_cb->ipv6_nd_rexmit_timer =2258				cpu_to_le32(*(uint32_t *)iface_param->value);2259		break;2260	case ISCSI_NET_PARAM_IPV6_ND_STALE_TMO:2261		if (iface_param->iface_num & 0x1)2262			break;2263		init_fw_cb->ipv6_nd_stale_timeout =2264				cpu_to_le32(*(uint32_t *)iface_param->value);2265		break;2266	case ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT:2267		if (iface_param->iface_num & 0x1)2268			break;2269		init_fw_cb->ipv6_dup_addr_detect_count = iface_param->value[0];2270		break;2271	case ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU:2272		if (iface_param->iface_num & 0x1)2273			break;2274		init_fw_cb->ipv6_gw_advrt_mtu =2275				cpu_to_le32(*(uint32_t *)iface_param->value);2276		break;2277	default:2278		ql4_printk(KERN_ERR, ha, "Unknown IPv6 param = %d\n",2279			   iface_param->param);2280		break;2281	}2282}2283 2284static void qla4xxx_set_ipv4(struct scsi_qla_host *ha,2285			     struct iscsi_iface_param_info *iface_param,2286			     struct addr_ctrl_blk *init_fw_cb)2287{2288	switch (iface_param->param) {2289	case ISCSI_NET_PARAM_IPV4_ADDR:2290		memcpy(init_fw_cb->ipv4_addr, iface_param->value,2291		       sizeof(init_fw_cb->ipv4_addr));2292		break;2293	case ISCSI_NET_PARAM_IPV4_SUBNET:2294		memcpy(init_fw_cb->ipv4_subnet,	iface_param->value,2295		       sizeof(init_fw_cb->ipv4_subnet));2296		break;2297	case ISCSI_NET_PARAM_IPV4_GW:2298		memcpy(init_fw_cb->ipv4_gw_addr, iface_param->value,2299		       sizeof(init_fw_cb->ipv4_gw_addr));2300		break;2301	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:2302		if (iface_param->value[0] == ISCSI_BOOTPROTO_DHCP)2303			init_fw_cb->ipv4_tcp_opts |=2304					cpu_to_le16(TCPOPT_DHCP_ENABLE);2305		else if (iface_param->value[0] == ISCSI_BOOTPROTO_STATIC)2306			init_fw_cb->ipv4_tcp_opts &=2307					cpu_to_le16(~TCPOPT_DHCP_ENABLE);2308		else2309			ql4_printk(KERN_ERR, ha, "Invalid IPv4 bootproto\n");2310		break;2311	case ISCSI_NET_PARAM_IFACE_ENABLE:2312		if (iface_param->value[0] == ISCSI_IFACE_ENABLE) {2313			init_fw_cb->ipv4_ip_opts |=2314				cpu_to_le16(IPOPT_IPV4_PROTOCOL_ENABLE);2315			qla4xxx_create_ipv4_iface(ha);2316		} else {2317			init_fw_cb->ipv4_ip_opts &=2318				cpu_to_le16(~IPOPT_IPV4_PROTOCOL_ENABLE &2319					    0xFFFF);2320			qla4xxx_destroy_ipv4_iface(ha);2321		}2322		break;2323	case ISCSI_NET_PARAM_VLAN_TAG:2324		if (iface_param->len != sizeof(init_fw_cb->ipv4_vlan_tag))2325			break;2326		init_fw_cb->ipv4_vlan_tag =2327				cpu_to_be16(*(uint16_t *)iface_param->value);2328		break;2329	case ISCSI_NET_PARAM_VLAN_ENABLED:2330		if (iface_param->value[0] == ISCSI_VLAN_ENABLE)2331			init_fw_cb->ipv4_ip_opts |=2332					cpu_to_le16(IPOPT_VLAN_TAGGING_ENABLE);2333		else2334			init_fw_cb->ipv4_ip_opts &=2335					cpu_to_le16(~IPOPT_VLAN_TAGGING_ENABLE);2336		break;2337	case ISCSI_NET_PARAM_MTU:2338		init_fw_cb->eth_mtu_size =2339				cpu_to_le16(*(uint16_t *)iface_param->value);2340		break;2341	case ISCSI_NET_PARAM_PORT:2342		init_fw_cb->ipv4_port =2343				cpu_to_le16(*(uint16_t *)iface_param->value);2344		break;2345	case ISCSI_NET_PARAM_DELAYED_ACK_EN:2346		if (iface_param->iface_num & 0x1)2347			break;2348		if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)2349			init_fw_cb->ipv4_tcp_opts |=2350				cpu_to_le16(TCPOPT_DELAYED_ACK_DISABLE);2351		else2352			init_fw_cb->ipv4_tcp_opts &=2353				cpu_to_le16(~TCPOPT_DELAYED_ACK_DISABLE &2354					    0xFFFF);2355		break;2356	case ISCSI_NET_PARAM_TCP_NAGLE_DISABLE:2357		if (iface_param->iface_num & 0x1)2358			break;2359		if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)2360			init_fw_cb->ipv4_tcp_opts |=2361				cpu_to_le16(TCPOPT_NAGLE_ALGO_DISABLE);2362		else2363			init_fw_cb->ipv4_tcp_opts &=2364				cpu_to_le16(~TCPOPT_NAGLE_ALGO_DISABLE);2365		break;2366	case ISCSI_NET_PARAM_TCP_WSF_DISABLE:2367		if (iface_param->iface_num & 0x1)2368			break;2369		if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)2370			init_fw_cb->ipv4_tcp_opts |=2371				cpu_to_le16(TCPOPT_WINDOW_SCALE_DISABLE);2372		else2373			init_fw_cb->ipv4_tcp_opts &=2374				cpu_to_le16(~TCPOPT_WINDOW_SCALE_DISABLE);2375		break;2376	case ISCSI_NET_PARAM_TCP_WSF:2377		if (iface_param->iface_num & 0x1)2378			break;2379		init_fw_cb->ipv4_tcp_wsf = iface_param->value[0];2380		break;2381	case ISCSI_NET_PARAM_TCP_TIMER_SCALE:2382		if (iface_param->iface_num & 0x1)2383			break;2384		init_fw_cb->ipv4_tcp_opts &= cpu_to_le16(~TCPOPT_TIMER_SCALE);2385		init_fw_cb->ipv4_tcp_opts |=2386				cpu_to_le16((iface_param->value[0] << 1) &2387					    TCPOPT_TIMER_SCALE);2388		break;2389	case ISCSI_NET_PARAM_TCP_TIMESTAMP_EN:2390		if (iface_param->iface_num & 0x1)2391			break;2392		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2393			init_fw_cb->ipv4_tcp_opts |=2394				cpu_to_le16(TCPOPT_TIMESTAMP_ENABLE);2395		else2396			init_fw_cb->ipv4_tcp_opts &=2397				cpu_to_le16(~TCPOPT_TIMESTAMP_ENABLE);2398		break;2399	case ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN:2400		if (iface_param->iface_num & 0x1)2401			break;2402		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2403			init_fw_cb->ipv4_tcp_opts |=2404				cpu_to_le16(TCPOPT_DNS_SERVER_IP_EN);2405		else2406			init_fw_cb->ipv4_tcp_opts &=2407				cpu_to_le16(~TCPOPT_DNS_SERVER_IP_EN);2408		break;2409	case ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN:2410		if (iface_param->iface_num & 0x1)2411			break;2412		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2413			init_fw_cb->ipv4_tcp_opts |=2414				cpu_to_le16(TCPOPT_SLP_DA_INFO_EN);2415		else2416			init_fw_cb->ipv4_tcp_opts &=2417				cpu_to_le16(~TCPOPT_SLP_DA_INFO_EN);2418		break;2419	case ISCSI_NET_PARAM_IPV4_TOS_EN:2420		if (iface_param->iface_num & 0x1)2421			break;2422		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2423			init_fw_cb->ipv4_ip_opts |=2424				cpu_to_le16(IPOPT_IPV4_TOS_EN);2425		else2426			init_fw_cb->ipv4_ip_opts &=2427				cpu_to_le16(~IPOPT_IPV4_TOS_EN);2428		break;2429	case ISCSI_NET_PARAM_IPV4_TOS:2430		if (iface_param->iface_num & 0x1)2431			break;2432		init_fw_cb->ipv4_tos = iface_param->value[0];2433		break;2434	case ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN:2435		if (iface_param->iface_num & 0x1)2436			break;2437		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2438			init_fw_cb->ipv4_ip_opts |=2439					cpu_to_le16(IPOPT_GRAT_ARP_EN);2440		else2441			init_fw_cb->ipv4_ip_opts &=2442					cpu_to_le16(~IPOPT_GRAT_ARP_EN);2443		break;2444	case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN:2445		if (iface_param->iface_num & 0x1)2446			break;2447		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2448			init_fw_cb->ipv4_ip_opts |=2449				cpu_to_le16(IPOPT_ALT_CID_EN);2450		else2451			init_fw_cb->ipv4_ip_opts &=2452				cpu_to_le16(~IPOPT_ALT_CID_EN);2453		break;2454	case ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID:2455		if (iface_param->iface_num & 0x1)2456			break;2457		memcpy(init_fw_cb->ipv4_dhcp_alt_cid, iface_param->value,2458		       (sizeof(init_fw_cb->ipv4_dhcp_alt_cid) - 1));2459		init_fw_cb->ipv4_dhcp_alt_cid_len =2460					strlen(init_fw_cb->ipv4_dhcp_alt_cid);2461		break;2462	case ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN:2463		if (iface_param->iface_num & 0x1)2464			break;2465		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2466			init_fw_cb->ipv4_ip_opts |=2467					cpu_to_le16(IPOPT_REQ_VID_EN);2468		else2469			init_fw_cb->ipv4_ip_opts &=2470					cpu_to_le16(~IPOPT_REQ_VID_EN);2471		break;2472	case ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN:2473		if (iface_param->iface_num & 0x1)2474			break;2475		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2476			init_fw_cb->ipv4_ip_opts |=2477					cpu_to_le16(IPOPT_USE_VID_EN);2478		else2479			init_fw_cb->ipv4_ip_opts &=2480					cpu_to_le16(~IPOPT_USE_VID_EN);2481		break;2482	case ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID:2483		if (iface_param->iface_num & 0x1)2484			break;2485		memcpy(init_fw_cb->ipv4_dhcp_vid, iface_param->value,2486		       (sizeof(init_fw_cb->ipv4_dhcp_vid) - 1));2487		init_fw_cb->ipv4_dhcp_vid_len =2488					strlen(init_fw_cb->ipv4_dhcp_vid);2489		break;2490	case ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN:2491		if (iface_param->iface_num & 0x1)2492			break;2493		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2494			init_fw_cb->ipv4_ip_opts |=2495					cpu_to_le16(IPOPT_LEARN_IQN_EN);2496		else2497			init_fw_cb->ipv4_ip_opts &=2498					cpu_to_le16(~IPOPT_LEARN_IQN_EN);2499		break;2500	case ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE:2501		if (iface_param->iface_num & 0x1)2502			break;2503		if (iface_param->value[0] == ISCSI_NET_PARAM_DISABLE)2504			init_fw_cb->ipv4_ip_opts |=2505				cpu_to_le16(IPOPT_FRAGMENTATION_DISABLE);2506		else2507			init_fw_cb->ipv4_ip_opts &=2508				cpu_to_le16(~IPOPT_FRAGMENTATION_DISABLE);2509		break;2510	case ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN:2511		if (iface_param->iface_num & 0x1)2512			break;2513		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2514			init_fw_cb->ipv4_ip_opts |=2515				cpu_to_le16(IPOPT_IN_FORWARD_EN);2516		else2517			init_fw_cb->ipv4_ip_opts &=2518				cpu_to_le16(~IPOPT_IN_FORWARD_EN);2519		break;2520	case ISCSI_NET_PARAM_REDIRECT_EN:2521		if (iface_param->iface_num & 0x1)2522			break;2523		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2524			init_fw_cb->ipv4_ip_opts |=2525				cpu_to_le16(IPOPT_ARP_REDIRECT_EN);2526		else2527			init_fw_cb->ipv4_ip_opts &=2528				cpu_to_le16(~IPOPT_ARP_REDIRECT_EN);2529		break;2530	case ISCSI_NET_PARAM_IPV4_TTL:2531		if (iface_param->iface_num & 0x1)2532			break;2533		init_fw_cb->ipv4_ttl = iface_param->value[0];2534		break;2535	default:2536		ql4_printk(KERN_ERR, ha, "Unknown IPv4 param = %d\n",2537			   iface_param->param);2538		break;2539	}2540}2541 2542static void qla4xxx_set_iscsi_param(struct scsi_qla_host *ha,2543				    struct iscsi_iface_param_info *iface_param,2544				    struct addr_ctrl_blk *init_fw_cb)2545{2546	switch (iface_param->param) {2547	case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO:2548		if (iface_param->iface_num & 0x1)2549			break;2550		init_fw_cb->def_timeout =2551				cpu_to_le16(*(uint16_t *)iface_param->value);2552		break;2553	case ISCSI_IFACE_PARAM_HDRDGST_EN:2554		if (iface_param->iface_num & 0x1)2555			break;2556		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2557			init_fw_cb->iscsi_opts |=2558				cpu_to_le16(ISCSIOPTS_HEADER_DIGEST_EN);2559		else2560			init_fw_cb->iscsi_opts &=2561				cpu_to_le16(~ISCSIOPTS_HEADER_DIGEST_EN);2562		break;2563	case ISCSI_IFACE_PARAM_DATADGST_EN:2564		if (iface_param->iface_num & 0x1)2565			break;2566		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2567			init_fw_cb->iscsi_opts |=2568				cpu_to_le16(ISCSIOPTS_DATA_DIGEST_EN);2569		else2570			init_fw_cb->iscsi_opts &=2571				cpu_to_le16(~ISCSIOPTS_DATA_DIGEST_EN);2572		break;2573	case ISCSI_IFACE_PARAM_IMM_DATA_EN:2574		if (iface_param->iface_num & 0x1)2575			break;2576		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2577			init_fw_cb->iscsi_opts |=2578				cpu_to_le16(ISCSIOPTS_IMMEDIATE_DATA_EN);2579		else2580			init_fw_cb->iscsi_opts &=2581				cpu_to_le16(~ISCSIOPTS_IMMEDIATE_DATA_EN);2582		break;2583	case ISCSI_IFACE_PARAM_INITIAL_R2T_EN:2584		if (iface_param->iface_num & 0x1)2585			break;2586		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2587			init_fw_cb->iscsi_opts |=2588				cpu_to_le16(ISCSIOPTS_INITIAL_R2T_EN);2589		else2590			init_fw_cb->iscsi_opts &=2591				cpu_to_le16(~ISCSIOPTS_INITIAL_R2T_EN);2592		break;2593	case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN:2594		if (iface_param->iface_num & 0x1)2595			break;2596		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2597			init_fw_cb->iscsi_opts |=2598				cpu_to_le16(ISCSIOPTS_DATA_SEQ_INORDER_EN);2599		else2600			init_fw_cb->iscsi_opts &=2601				cpu_to_le16(~ISCSIOPTS_DATA_SEQ_INORDER_EN);2602		break;2603	case ISCSI_IFACE_PARAM_PDU_INORDER_EN:2604		if (iface_param->iface_num & 0x1)2605			break;2606		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2607			init_fw_cb->iscsi_opts |=2608				cpu_to_le16(ISCSIOPTS_DATA_PDU_INORDER_EN);2609		else2610			init_fw_cb->iscsi_opts &=2611				cpu_to_le16(~ISCSIOPTS_DATA_PDU_INORDER_EN);2612		break;2613	case ISCSI_IFACE_PARAM_ERL:2614		if (iface_param->iface_num & 0x1)2615			break;2616		init_fw_cb->iscsi_opts &= cpu_to_le16(~ISCSIOPTS_ERL);2617		init_fw_cb->iscsi_opts |= cpu_to_le16(iface_param->value[0] &2618						      ISCSIOPTS_ERL);2619		break;2620	case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH:2621		if (iface_param->iface_num & 0x1)2622			break;2623		init_fw_cb->iscsi_max_pdu_size =2624				cpu_to_le32(*(uint32_t *)iface_param->value) /2625				BYTE_UNITS;2626		break;2627	case ISCSI_IFACE_PARAM_FIRST_BURST:2628		if (iface_param->iface_num & 0x1)2629			break;2630		init_fw_cb->iscsi_fburst_len =2631				cpu_to_le32(*(uint32_t *)iface_param->value) /2632				BYTE_UNITS;2633		break;2634	case ISCSI_IFACE_PARAM_MAX_R2T:2635		if (iface_param->iface_num & 0x1)2636			break;2637		init_fw_cb->iscsi_max_outstnd_r2t =2638				cpu_to_le16(*(uint16_t *)iface_param->value);2639		break;2640	case ISCSI_IFACE_PARAM_MAX_BURST:2641		if (iface_param->iface_num & 0x1)2642			break;2643		init_fw_cb->iscsi_max_burst_len =2644				cpu_to_le32(*(uint32_t *)iface_param->value) /2645				BYTE_UNITS;2646		break;2647	case ISCSI_IFACE_PARAM_CHAP_AUTH_EN:2648		if (iface_param->iface_num & 0x1)2649			break;2650		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2651			init_fw_cb->iscsi_opts |=2652				cpu_to_le16(ISCSIOPTS_CHAP_AUTH_EN);2653		else2654			init_fw_cb->iscsi_opts &=2655				cpu_to_le16(~ISCSIOPTS_CHAP_AUTH_EN);2656		break;2657	case ISCSI_IFACE_PARAM_BIDI_CHAP_EN:2658		if (iface_param->iface_num & 0x1)2659			break;2660		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2661			init_fw_cb->iscsi_opts |=2662				cpu_to_le16(ISCSIOPTS_BIDI_CHAP_EN);2663		else2664			init_fw_cb->iscsi_opts &=2665				cpu_to_le16(~ISCSIOPTS_BIDI_CHAP_EN);2666		break;2667	case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL:2668		if (iface_param->iface_num & 0x1)2669			break;2670		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2671			init_fw_cb->iscsi_opts |=2672				cpu_to_le16(ISCSIOPTS_DISCOVERY_AUTH_EN);2673		else2674			init_fw_cb->iscsi_opts &=2675				cpu_to_le16(~ISCSIOPTS_DISCOVERY_AUTH_EN);2676		break;2677	case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN:2678		if (iface_param->iface_num & 0x1)2679			break;2680		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2681			init_fw_cb->iscsi_opts |=2682				cpu_to_le16(ISCSIOPTS_DISCOVERY_LOGOUT_EN);2683		else2684			init_fw_cb->iscsi_opts &=2685				cpu_to_le16(~ISCSIOPTS_DISCOVERY_LOGOUT_EN);2686		break;2687	case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN:2688		if (iface_param->iface_num & 0x1)2689			break;2690		if (iface_param->value[0] == ISCSI_NET_PARAM_ENABLE)2691			init_fw_cb->iscsi_opts |=2692				cpu_to_le16(ISCSIOPTS_STRICT_LOGIN_COMP_EN);2693		else2694			init_fw_cb->iscsi_opts &=2695				cpu_to_le16(~ISCSIOPTS_STRICT_LOGIN_COMP_EN);2696		break;2697	default:2698		ql4_printk(KERN_ERR, ha, "Unknown iscsi param = %d\n",2699			   iface_param->param);2700		break;2701	}2702}2703 2704static void2705qla4xxx_initcb_to_acb(struct addr_ctrl_blk *init_fw_cb)2706{2707	struct addr_ctrl_blk_def *acb;2708	acb = (struct addr_ctrl_blk_def *)init_fw_cb;2709	memset(acb->reserved1, 0, sizeof(acb->reserved1));2710	memset(acb->reserved2, 0, sizeof(acb->reserved2));2711	memset(acb->reserved3, 0, sizeof(acb->reserved3));2712	memset(acb->reserved4, 0, sizeof(acb->reserved4));2713	memset(acb->reserved5, 0, sizeof(acb->reserved5));2714	memset(acb->reserved6, 0, sizeof(acb->reserved6));2715	memset(acb->reserved7, 0, sizeof(acb->reserved7));2716	memset(acb->reserved8, 0, sizeof(acb->reserved8));2717	memset(acb->reserved9, 0, sizeof(acb->reserved9));2718	memset(acb->reserved10, 0, sizeof(acb->reserved10));2719	memset(acb->reserved11, 0, sizeof(acb->reserved11));2720	memset(acb->reserved12, 0, sizeof(acb->reserved12));2721	memset(acb->reserved13, 0, sizeof(acb->reserved13));2722	memset(acb->reserved14, 0, sizeof(acb->reserved14));2723	memset(acb->reserved15, 0, sizeof(acb->reserved15));2724}2725 2726static int2727qla4xxx_iface_set_param(struct Scsi_Host *shost, void *data, uint32_t len)2728{2729	struct scsi_qla_host *ha = to_qla_host(shost);2730	int rval = 0;2731	struct iscsi_iface_param_info *iface_param = NULL;2732	struct addr_ctrl_blk *init_fw_cb = NULL;2733	dma_addr_t init_fw_cb_dma;2734	uint32_t mbox_cmd[MBOX_REG_COUNT];2735	uint32_t mbox_sts[MBOX_REG_COUNT];2736	uint32_t rem = len;2737	struct nlattr *attr;2738 2739	init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,2740					sizeof(struct addr_ctrl_blk),2741					&init_fw_cb_dma, GFP_KERNEL);2742	if (!init_fw_cb) {2743		ql4_printk(KERN_ERR, ha, "%s: Unable to alloc init_cb\n",2744			   __func__);2745		return -ENOMEM;2746	}2747 2748	memset(&mbox_cmd, 0, sizeof(mbox_cmd));2749	memset(&mbox_sts, 0, sizeof(mbox_sts));2750 2751	if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma)) {2752		ql4_printk(KERN_ERR, ha, "%s: get ifcb failed\n", __func__);2753		rval = -EIO;2754		goto exit_init_fw_cb;2755	}2756 2757	nla_for_each_attr(attr, data, len, rem) {2758		if (nla_len(attr) < sizeof(*iface_param)) {2759			rval = -EINVAL;2760			goto exit_init_fw_cb;2761		}2762 2763		iface_param = nla_data(attr);2764 2765		if (iface_param->param_type == ISCSI_NET_PARAM) {2766			switch (iface_param->iface_type) {2767			case ISCSI_IFACE_TYPE_IPV4:2768				switch (iface_param->iface_num) {2769				case 0:2770					qla4xxx_set_ipv4(ha, iface_param,2771							 init_fw_cb);2772					break;2773				default:2774				/* Cannot have more than one IPv4 interface */2775					ql4_printk(KERN_ERR, ha,2776						   "Invalid IPv4 iface number = %d\n",2777						   iface_param->iface_num);2778					break;2779				}2780				break;2781			case ISCSI_IFACE_TYPE_IPV6:2782				switch (iface_param->iface_num) {2783				case 0:2784				case 1:2785					qla4xxx_set_ipv6(ha, iface_param,2786							 init_fw_cb);2787					break;2788				default:2789				/* Cannot have more than two IPv6 interface */2790					ql4_printk(KERN_ERR, ha,2791						   "Invalid IPv6 iface number = %d\n",2792						   iface_param->iface_num);2793					break;2794				}2795				break;2796			default:2797				ql4_printk(KERN_ERR, ha,2798					   "Invalid iface type\n");2799				break;2800			}2801		} else if (iface_param->param_type == ISCSI_IFACE_PARAM) {2802				qla4xxx_set_iscsi_param(ha, iface_param,2803							init_fw_cb);2804		} else {2805			continue;2806		}2807	}2808 2809	init_fw_cb->cookie = cpu_to_le32(0x11BEAD5A);2810 2811	rval = qla4xxx_set_flash(ha, init_fw_cb_dma, FLASH_SEGMENT_IFCB,2812				 sizeof(struct addr_ctrl_blk),2813				 FLASH_OPT_RMW_COMMIT);2814	if (rval != QLA_SUCCESS) {2815		ql4_printk(KERN_ERR, ha, "%s: set flash mbx failed\n",2816			   __func__);2817		rval = -EIO;2818		goto exit_init_fw_cb;2819	}2820 2821	rval = qla4xxx_disable_acb(ha);2822	if (rval != QLA_SUCCESS) {2823		ql4_printk(KERN_ERR, ha, "%s: disable acb mbx failed\n",2824			   __func__);2825		rval = -EIO;2826		goto exit_init_fw_cb;2827	}2828 2829	wait_for_completion_timeout(&ha->disable_acb_comp,2830				    DISABLE_ACB_TOV * HZ);2831 2832	qla4xxx_initcb_to_acb(init_fw_cb);2833 2834	rval = qla4xxx_set_acb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma);2835	if (rval != QLA_SUCCESS) {2836		ql4_printk(KERN_ERR, ha, "%s: set acb mbx failed\n",2837			   __func__);2838		rval = -EIO;2839		goto exit_init_fw_cb;2840	}2841 2842	memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));2843	qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb,2844				  init_fw_cb_dma);2845 2846exit_init_fw_cb:2847	dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),2848			  init_fw_cb, init_fw_cb_dma);2849 2850	return rval;2851}2852 2853static int qla4xxx_session_get_param(struct iscsi_cls_session *cls_sess,2854				     enum iscsi_param param, char *buf)2855{2856	struct iscsi_session *sess = cls_sess->dd_data;2857	struct ddb_entry *ddb_entry = sess->dd_data;2858	struct scsi_qla_host *ha = ddb_entry->ha;2859	struct iscsi_cls_conn *cls_conn = ddb_entry->conn;2860	struct ql4_chap_table chap_tbl;2861	int rval, len;2862	uint16_t idx;2863 2864	memset(&chap_tbl, 0, sizeof(chap_tbl));2865	switch (param) {2866	case ISCSI_PARAM_CHAP_IN_IDX:2867		rval = qla4xxx_get_chap_index(ha, sess->username_in,2868					      sess->password_in, BIDI_CHAP,2869					      &idx);2870		if (rval)2871			len = sprintf(buf, "\n");2872		else2873			len = sprintf(buf, "%hu\n", idx);2874		break;2875	case ISCSI_PARAM_CHAP_OUT_IDX:2876		if (ddb_entry->ddb_type == FLASH_DDB) {2877			if (ddb_entry->chap_tbl_idx != INVALID_ENTRY) {2878				idx = ddb_entry->chap_tbl_idx;2879				rval = QLA_SUCCESS;2880			} else {2881				rval = QLA_ERROR;2882			}2883		} else {2884			rval = qla4xxx_get_chap_index(ha, sess->username,2885						      sess->password,2886						      LOCAL_CHAP, &idx);2887		}2888		if (rval)2889			len = sprintf(buf, "\n");2890		else2891			len = sprintf(buf, "%hu\n", idx);2892		break;2893	case ISCSI_PARAM_USERNAME:2894	case ISCSI_PARAM_PASSWORD:2895		/* First, populate session username and password for FLASH DDB,2896		 * if not already done. This happens when session login fails2897		 * for a FLASH DDB.2898		 */2899		if (ddb_entry->ddb_type == FLASH_DDB &&2900		    ddb_entry->chap_tbl_idx != INVALID_ENTRY &&2901		    !sess->username && !sess->password) {2902			idx = ddb_entry->chap_tbl_idx;2903			rval = qla4xxx_get_uni_chap_at_index(ha, chap_tbl.name,2904							    chap_tbl.secret,2905							    idx);2906			if (!rval) {2907				iscsi_set_param(cls_conn, ISCSI_PARAM_USERNAME,2908						(char *)chap_tbl.name,2909						strlen((char *)chap_tbl.name));2910				iscsi_set_param(cls_conn, ISCSI_PARAM_PASSWORD,2911						(char *)chap_tbl.secret,2912						chap_tbl.secret_len);2913			}2914		}2915		fallthrough;2916	default:2917		return iscsi_session_get_param(cls_sess, param, buf);2918	}2919 2920	return len;2921}2922 2923static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn,2924				  enum iscsi_param param, char *buf)2925{2926	struct iscsi_conn *conn;2927	struct qla_conn *qla_conn;2928	struct sockaddr *dst_addr;2929 2930	conn = cls_conn->dd_data;2931	qla_conn = conn->dd_data;2932	dst_addr = (struct sockaddr *)&qla_conn->qla_ep->dst_addr;2933 2934	switch (param) {2935	case ISCSI_PARAM_CONN_PORT:2936	case ISCSI_PARAM_CONN_ADDRESS:2937		return iscsi_conn_get_addr_param((struct sockaddr_storage *)2938						 dst_addr, param, buf);2939	default:2940		return iscsi_conn_get_param(cls_conn, param, buf);2941	}2942}2943 2944int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index)2945{2946	uint32_t mbx_sts = 0;2947	uint16_t tmp_ddb_index;2948	int ret;2949 2950get_ddb_index:2951	tmp_ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES);2952 2953	if (tmp_ddb_index >= MAX_DDB_ENTRIES) {2954		DEBUG2(ql4_printk(KERN_INFO, ha,2955				  "Free DDB index not available\n"));2956		ret = QLA_ERROR;2957		goto exit_get_ddb_index;2958	}2959 2960	if (test_and_set_bit(tmp_ddb_index, ha->ddb_idx_map))2961		goto get_ddb_index;2962 2963	DEBUG2(ql4_printk(KERN_INFO, ha,2964			  "Found a free DDB index at %d\n", tmp_ddb_index));2965	ret = qla4xxx_req_ddb_entry(ha, tmp_ddb_index, &mbx_sts);2966	if (ret == QLA_ERROR) {2967		if (mbx_sts == MBOX_STS_COMMAND_ERROR) {2968			ql4_printk(KERN_INFO, ha,2969				   "DDB index = %d not available trying next\n",2970				   tmp_ddb_index);2971			goto get_ddb_index;2972		}2973		DEBUG2(ql4_printk(KERN_INFO, ha,2974				  "Free FW DDB not available\n"));2975	}2976 2977	*ddb_index = tmp_ddb_index;2978 2979exit_get_ddb_index:2980	return ret;2981}2982 2983static int qla4xxx_match_ipaddress(struct scsi_qla_host *ha,2984				   struct ddb_entry *ddb_entry,2985				   char *existing_ipaddr,2986				   char *user_ipaddr)2987{2988	uint8_t dst_ipaddr[IPv6_ADDR_LEN];2989	char formatted_ipaddr[DDB_IPADDR_LEN];2990	int status = QLA_SUCCESS, ret = 0;2991 2992	if (ddb_entry->fw_ddb_entry.options & DDB_OPT_IPV6_DEVICE) {2993		ret = in6_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr,2994			       '\0', NULL);2995		if (ret == 0) {2996			status = QLA_ERROR;2997			goto out_match;2998		}2999		ret = sprintf(formatted_ipaddr, "%pI6", dst_ipaddr);3000	} else {3001		ret = in4_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr,3002			       '\0', NULL);3003		if (ret == 0) {3004			status = QLA_ERROR;3005			goto out_match;3006		}3007		ret = sprintf(formatted_ipaddr, "%pI4", dst_ipaddr);3008	}3009 3010	if (strcmp(existing_ipaddr, formatted_ipaddr))3011		status = QLA_ERROR;3012 3013out_match:3014	return status;3015}3016 3017static int qla4xxx_match_fwdb_session(struct scsi_qla_host *ha,3018				      struct iscsi_cls_conn *cls_conn)3019{3020	int idx = 0, max_ddbs, rval;3021	struct iscsi_cls_session *cls_sess = iscsi_conn_to_session(cls_conn);3022	struct iscsi_session *sess, *existing_sess;3023	struct iscsi_conn *conn, *existing_conn;3024	struct ddb_entry *ddb_entry;3025 3026	sess = cls_sess->dd_data;3027	conn = cls_conn->dd_data;3028 3029	if (sess->targetname == NULL ||3030	    conn->persistent_address == NULL ||3031	    conn->persistent_port == 0)3032		return QLA_ERROR;3033 3034	max_ddbs =  is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :3035				     MAX_DEV_DB_ENTRIES;3036 3037	for (idx = 0; idx < max_ddbs; idx++) {3038		ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);3039		if (ddb_entry == NULL)3040			continue;3041 3042		if (ddb_entry->ddb_type != FLASH_DDB)3043			continue;3044 3045		existing_sess = ddb_entry->sess->dd_data;3046		existing_conn = ddb_entry->conn->dd_data;3047 3048		if (existing_sess->targetname == NULL ||3049		    existing_conn->persistent_address == NULL ||3050		    existing_conn->persistent_port == 0)3051			continue;3052 3053		DEBUG2(ql4_printk(KERN_INFO, ha,3054				  "IQN = %s User IQN = %s\n",3055				  existing_sess->targetname,3056				  sess->targetname));3057 3058		DEBUG2(ql4_printk(KERN_INFO, ha,3059				  "IP = %s User IP = %s\n",3060				  existing_conn->persistent_address,3061				  conn->persistent_address));3062 3063		DEBUG2(ql4_printk(KERN_INFO, ha,3064				  "Port = %d User Port = %d\n",3065				  existing_conn->persistent_port,3066				  conn->persistent_port));3067 3068		if (strcmp(existing_sess->targetname, sess->targetname))3069			continue;3070		rval = qla4xxx_match_ipaddress(ha, ddb_entry,3071					existing_conn->persistent_address,3072					conn->persistent_address);3073		if (rval == QLA_ERROR)3074			continue;3075		if (existing_conn->persistent_port != conn->persistent_port)3076			continue;3077		break;3078	}3079 3080	if (idx == max_ddbs)3081		return QLA_ERROR;3082 3083	DEBUG2(ql4_printk(KERN_INFO, ha,3084			  "Match found in fwdb sessions\n"));3085	return QLA_SUCCESS;3086}3087 3088static struct iscsi_cls_session *3089qla4xxx_session_create(struct iscsi_endpoint *ep,3090			uint16_t cmds_max, uint16_t qdepth,3091			uint32_t initial_cmdsn)3092{3093	struct iscsi_cls_session *cls_sess;3094	struct scsi_qla_host *ha;3095	struct qla_endpoint *qla_ep;3096	struct ddb_entry *ddb_entry;3097	uint16_t ddb_index;3098	struct iscsi_session *sess;3099	int ret;3100 3101	if (!ep) {3102		printk(KERN_ERR "qla4xxx: missing ep.\n");3103		return NULL;3104	}3105 3106	qla_ep = ep->dd_data;3107	ha = to_qla_host(qla_ep->host);3108	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: host: %ld\n", __func__,3109			  ha->host_no));3110 3111	ret = qla4xxx_get_ddb_index(ha, &ddb_index);3112	if (ret == QLA_ERROR)3113		return NULL;3114 3115	cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, qla_ep->host,3116				       cmds_max, sizeof(struct ddb_entry),3117				       sizeof(struct ql4_task_data),3118				       initial_cmdsn, ddb_index);3119	if (!cls_sess)3120		return NULL;3121 3122	sess = cls_sess->dd_data;3123	ddb_entry = sess->dd_data;3124	ddb_entry->fw_ddb_index = ddb_index;3125	ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE;3126	ddb_entry->ha = ha;3127	ddb_entry->sess = cls_sess;3128	ddb_entry->unblock_sess = qla4xxx_unblock_ddb;3129	ddb_entry->ddb_change = qla4xxx_ddb_change;3130	clear_bit(DDB_CONN_CLOSE_FAILURE, &ddb_entry->flags);3131	cls_sess->recovery_tmo = ql4xsess_recovery_tmo;3132	ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry;3133	ha->tot_ddbs++;3134 3135	return cls_sess;3136}3137 3138static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess)3139{3140	struct iscsi_session *sess;3141	struct ddb_entry *ddb_entry;3142	struct scsi_qla_host *ha;3143	unsigned long flags, wtime;3144	struct dev_db_entry *fw_ddb_entry = NULL;3145	dma_addr_t fw_ddb_entry_dma;3146	uint32_t ddb_state;3147	int ret;3148 3149	sess = cls_sess->dd_data;3150	ddb_entry = sess->dd_data;3151	ha = ddb_entry->ha;3152	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: host: %ld\n", __func__,3153			  ha->host_no));3154 3155	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),3156					  &fw_ddb_entry_dma, GFP_KERNEL);3157	if (!fw_ddb_entry) {3158		ql4_printk(KERN_ERR, ha,3159			   "%s: Unable to allocate dma buffer\n", __func__);3160		goto destroy_session;3161	}3162 3163	wtime = jiffies + (HZ * LOGOUT_TOV);3164	do {3165		ret = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index,3166					      fw_ddb_entry, fw_ddb_entry_dma,3167					      NULL, NULL, &ddb_state, NULL,3168					      NULL, NULL);3169		if (ret == QLA_ERROR)3170			goto destroy_session;3171 3172		if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) ||3173		    (ddb_state == DDB_DS_SESSION_FAILED))3174			goto destroy_session;3175 3176		schedule_timeout_uninterruptible(HZ);3177	} while ((time_after(wtime, jiffies)));3178 3179destroy_session:3180	qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);3181	if (test_and_clear_bit(DDB_CONN_CLOSE_FAILURE, &ddb_entry->flags))3182		clear_bit(ddb_entry->fw_ddb_index, ha->ddb_idx_map);3183	spin_lock_irqsave(&ha->hardware_lock, flags);3184	qla4xxx_free_ddb(ha, ddb_entry);3185	spin_unlock_irqrestore(&ha->hardware_lock, flags);3186 3187	iscsi_session_teardown(cls_sess);3188 3189	if (fw_ddb_entry)3190		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),3191				  fw_ddb_entry, fw_ddb_entry_dma);3192}3193 3194static struct iscsi_cls_conn *3195qla4xxx_conn_create(struct iscsi_cls_session *cls_sess, uint32_t conn_idx)3196{3197	struct iscsi_cls_conn *cls_conn;3198	struct iscsi_session *sess;3199	struct ddb_entry *ddb_entry;3200	struct scsi_qla_host *ha;3201 3202	cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn),3203				    conn_idx);3204	if (!cls_conn) {3205		pr_info("%s: Can not create connection for conn_idx = %u\n",3206			__func__, conn_idx);3207		return NULL;3208	}3209 3210	sess = cls_sess->dd_data;3211	ddb_entry = sess->dd_data;3212	ddb_entry->conn = cls_conn;3213 3214	ha = ddb_entry->ha;3215	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: conn_idx = %u\n", __func__,3216			  conn_idx));3217	return cls_conn;3218}3219 3220static int qla4xxx_conn_bind(struct iscsi_cls_session *cls_session,3221			     struct iscsi_cls_conn *cls_conn,3222			     uint64_t transport_fd, int is_leading)3223{3224	struct iscsi_conn *conn;3225	struct qla_conn *qla_conn;3226	struct iscsi_endpoint *ep;3227	struct ddb_entry *ddb_entry;3228	struct scsi_qla_host *ha;3229	struct iscsi_session *sess;3230 3231	sess = cls_session->dd_data;3232	ddb_entry = sess->dd_data;3233	ha = ddb_entry->ha;3234 3235	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: sid = %d, cid = %d\n", __func__,3236			  cls_session->sid, cls_conn->cid));3237 3238	if (iscsi_conn_bind(cls_session, cls_conn, is_leading))3239		return -EINVAL;3240	ep = iscsi_lookup_endpoint(transport_fd);3241	if (!ep)3242		return -EINVAL;3243	conn = cls_conn->dd_data;3244	qla_conn = conn->dd_data;3245	qla_conn->qla_ep = ep->dd_data;3246	iscsi_put_endpoint(ep);3247	return 0;3248}3249 3250static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn)3251{3252	struct iscsi_cls_session *cls_sess = iscsi_conn_to_session(cls_conn);3253	struct iscsi_session *sess;3254	struct ddb_entry *ddb_entry;3255	struct scsi_qla_host *ha;3256	struct dev_db_entry *fw_ddb_entry = NULL;3257	dma_addr_t fw_ddb_entry_dma;3258	uint32_t mbx_sts = 0;3259	int ret = 0;3260	int status = QLA_SUCCESS;3261 3262	sess = cls_sess->dd_data;3263	ddb_entry = sess->dd_data;3264	ha = ddb_entry->ha;3265	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: sid = %d, cid = %d\n", __func__,3266			  cls_sess->sid, cls_conn->cid));3267 3268	/* Check if we have  matching FW DDB, if yes then do not3269	 * login to this target. This could cause target to logout previous3270	 * connection3271	 */3272	ret = qla4xxx_match_fwdb_session(ha, cls_conn);3273	if (ret == QLA_SUCCESS) {3274		ql4_printk(KERN_INFO, ha,3275			   "Session already exist in FW.\n");3276		ret = -EEXIST;3277		goto exit_conn_start;3278	}3279 3280	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),3281					  &fw_ddb_entry_dma, GFP_KERNEL);3282	if (!fw_ddb_entry) {3283		ql4_printk(KERN_ERR, ha,3284			   "%s: Unable to allocate dma buffer\n", __func__);3285		ret = -ENOMEM;3286		goto exit_conn_start;3287	}3288 3289	ret = qla4xxx_set_param_ddbentry(ha, ddb_entry, cls_conn, &mbx_sts);3290	if (ret) {3291		/* If iscsid is stopped and started then no need to do3292		* set param again since ddb state will be already3293		* active and FW does not allow set ddb to an3294		* active session.3295		*/3296		if (mbx_sts)3297			if (ddb_entry->fw_ddb_device_state ==3298						DDB_DS_SESSION_ACTIVE) {3299				ddb_entry->unblock_sess(ddb_entry->sess);3300				goto exit_set_param;3301			}3302 3303		ql4_printk(KERN_ERR, ha, "%s: Failed set param for index[%d]\n",3304			   __func__, ddb_entry->fw_ddb_index);3305		goto exit_conn_start;3306	}3307 3308	status = qla4xxx_conn_open(ha, ddb_entry->fw_ddb_index);3309	if (status == QLA_ERROR) {3310		ql4_printk(KERN_ERR, ha, "%s: Login failed: %s\n", __func__,3311			   sess->targetname);3312		ret = -EINVAL;3313		goto exit_conn_start;3314	}3315 3316	if (ddb_entry->fw_ddb_device_state == DDB_DS_NO_CONNECTION_ACTIVE)3317		ddb_entry->fw_ddb_device_state = DDB_DS_LOGIN_IN_PROCESS;3318 3319	DEBUG2(printk(KERN_INFO "%s: DDB state [%d]\n", __func__,3320		      ddb_entry->fw_ddb_device_state));3321 3322exit_set_param:3323	ret = 0;3324 3325exit_conn_start:3326	if (fw_ddb_entry)3327		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),3328				  fw_ddb_entry, fw_ddb_entry_dma);3329	return ret;3330}3331 3332static void qla4xxx_conn_destroy(struct iscsi_cls_conn *cls_conn)3333{3334	struct iscsi_cls_session *cls_sess = iscsi_conn_to_session(cls_conn);3335	struct iscsi_session *sess;3336	struct scsi_qla_host *ha;3337	struct ddb_entry *ddb_entry;3338	int options;3339 3340	sess = cls_sess->dd_data;3341	ddb_entry = sess->dd_data;3342	ha = ddb_entry->ha;3343	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: cid = %d\n", __func__,3344			  cls_conn->cid));3345 3346	options = LOGOUT_OPTION_CLOSE_SESSION;3347	if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) == QLA_ERROR)3348		ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", __func__);3349}3350 3351static void qla4xxx_task_work(struct work_struct *wdata)3352{3353	struct ql4_task_data *task_data;3354	struct scsi_qla_host *ha;3355	struct passthru_status *sts;3356	struct iscsi_task *task;3357	struct iscsi_hdr *hdr;3358	uint8_t *data;3359	uint32_t data_len;3360	struct iscsi_conn *conn;3361	int hdr_len;3362	itt_t itt;3363 3364	task_data = container_of(wdata, struct ql4_task_data, task_work);3365	ha = task_data->ha;3366	task = task_data->task;3367	sts = &task_data->sts;3368	hdr_len = sizeof(struct iscsi_hdr);3369 3370	DEBUG3(printk(KERN_INFO "Status returned\n"));3371	DEBUG3(qla4xxx_dump_buffer(sts, 64));3372	DEBUG3(printk(KERN_INFO "Response buffer"));3373	DEBUG3(qla4xxx_dump_buffer(task_data->resp_buffer, 64));3374 3375	conn = task->conn;3376 3377	switch (sts->completionStatus) {3378	case PASSTHRU_STATUS_COMPLETE:3379		hdr = (struct iscsi_hdr *)task_data->resp_buffer;3380		/* Assign back the itt in hdr, until we use the PREASSIGN_TAG */3381		itt = sts->handle;3382		hdr->itt = itt;3383		data = task_data->resp_buffer + hdr_len;3384		data_len = task_data->resp_len - hdr_len;3385		iscsi_complete_pdu(conn, hdr, data, data_len);3386		break;3387	default:3388		ql4_printk(KERN_ERR, ha, "Passthru failed status = 0x%x\n",3389			   sts->completionStatus);3390		break;3391	}3392	return;3393}3394 3395static int qla4xxx_alloc_pdu(struct iscsi_task *task, uint8_t opcode)3396{3397	struct ql4_task_data *task_data;3398	struct iscsi_session *sess;3399	struct ddb_entry *ddb_entry;3400	struct scsi_qla_host *ha;3401	int hdr_len;3402 3403	sess = task->conn->session;3404	ddb_entry = sess->dd_data;3405	ha = ddb_entry->ha;3406	task_data = task->dd_data;3407	memset(task_data, 0, sizeof(struct ql4_task_data));3408 3409	if (task->sc) {3410		ql4_printk(KERN_INFO, ha,3411			   "%s: SCSI Commands not implemented\n", __func__);3412		return -EINVAL;3413	}3414 3415	hdr_len = sizeof(struct iscsi_hdr);3416	task_data->ha = ha;3417	task_data->task = task;3418 3419	if (task->data_count) {3420		task_data->data_dma = dma_map_single(&ha->pdev->dev, task->data,3421						     task->data_count,3422						     DMA_TO_DEVICE);3423	}3424 3425	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: MaxRecvLen %u, iscsi hrd %d\n",3426		      __func__, task->conn->max_recv_dlength, hdr_len));3427 3428	task_data->resp_len = task->conn->max_recv_dlength + hdr_len;3429	task_data->resp_buffer = dma_alloc_coherent(&ha->pdev->dev,3430						    task_data->resp_len,3431						    &task_data->resp_dma,3432						    GFP_ATOMIC);3433	if (!task_data->resp_buffer)3434		goto exit_alloc_pdu;3435 3436	task_data->req_len = task->data_count + hdr_len;3437	task_data->req_buffer = dma_alloc_coherent(&ha->pdev->dev,3438						   task_data->req_len,3439						   &task_data->req_dma,3440						   GFP_ATOMIC);3441	if (!task_data->req_buffer)3442		goto exit_alloc_pdu;3443 3444	task->hdr = task_data->req_buffer;3445 3446	INIT_WORK(&task_data->task_work, qla4xxx_task_work);3447 3448	return 0;3449 3450exit_alloc_pdu:3451	if (task_data->resp_buffer)3452		dma_free_coherent(&ha->pdev->dev, task_data->resp_len,3453				  task_data->resp_buffer, task_data->resp_dma);3454 3455	if (task_data->req_buffer)3456		dma_free_coherent(&ha->pdev->dev, task_data->req_len,3457				  task_data->req_buffer, task_data->req_dma);3458	return -ENOMEM;3459}3460 3461static void qla4xxx_task_cleanup(struct iscsi_task *task)3462{3463	struct ql4_task_data *task_data;3464	struct iscsi_session *sess;3465	struct ddb_entry *ddb_entry;3466	struct scsi_qla_host *ha;3467	int hdr_len;3468 3469	hdr_len = sizeof(struct iscsi_hdr);3470	sess = task->conn->session;3471	ddb_entry = sess->dd_data;3472	ha = ddb_entry->ha;3473	task_data = task->dd_data;3474 3475	if (task->data_count) {3476		dma_unmap_single(&ha->pdev->dev, task_data->data_dma,3477				 task->data_count, DMA_TO_DEVICE);3478	}3479 3480	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: MaxRecvLen %u, iscsi hrd %d\n",3481		      __func__, task->conn->max_recv_dlength, hdr_len));3482 3483	dma_free_coherent(&ha->pdev->dev, task_data->resp_len,3484			  task_data->resp_buffer, task_data->resp_dma);3485	dma_free_coherent(&ha->pdev->dev, task_data->req_len,3486			  task_data->req_buffer, task_data->req_dma);3487	return;3488}3489 3490static int qla4xxx_task_xmit(struct iscsi_task *task)3491{3492	struct scsi_cmnd *sc = task->sc;3493	struct iscsi_session *sess = task->conn->session;3494	struct ddb_entry *ddb_entry = sess->dd_data;3495	struct scsi_qla_host *ha = ddb_entry->ha;3496 3497	if (!sc)3498		return qla4xxx_send_passthru0(task);3499 3500	ql4_printk(KERN_INFO, ha, "%s: scsi cmd xmit not implemented\n",3501		   __func__);3502	return -ENOSYS;3503}3504 3505static int qla4xxx_copy_from_fwddb_param(struct iscsi_bus_flash_session *sess,3506					 struct iscsi_bus_flash_conn *conn,3507					 struct dev_db_entry *fw_ddb_entry)3508{3509	unsigned long options = 0;3510	int rc = 0;3511 3512	options = le16_to_cpu(fw_ddb_entry->options);3513	conn->is_fw_assigned_ipv6 = test_bit(OPT_IS_FW_ASSIGNED_IPV6, &options);3514	if (test_bit(OPT_IPV6_DEVICE, &options)) {3515		rc = iscsi_switch_str_param(&sess->portal_type,3516					    PORTAL_TYPE_IPV6);3517		if (rc)3518			goto exit_copy;3519	} else {3520		rc = iscsi_switch_str_param(&sess->portal_type,3521					    PORTAL_TYPE_IPV4);3522		if (rc)3523			goto exit_copy;3524	}3525 3526	sess->auto_snd_tgt_disable = test_bit(OPT_AUTO_SENDTGTS_DISABLE,3527					      &options);3528	sess->discovery_sess = test_bit(OPT_DISC_SESSION, &options);3529	sess->entry_state = test_bit(OPT_ENTRY_STATE, &options);3530 3531	options = le16_to_cpu(fw_ddb_entry->iscsi_options);3532	conn->hdrdgst_en = test_bit(ISCSIOPT_HEADER_DIGEST_EN, &options);3533	conn->datadgst_en = test_bit(ISCSIOPT_DATA_DIGEST_EN, &options);3534	sess->imm_data_en = test_bit(ISCSIOPT_IMMEDIATE_DATA_EN, &options);3535	sess->initial_r2t_en = test_bit(ISCSIOPT_INITIAL_R2T_EN, &options);3536	sess->dataseq_inorder_en = test_bit(ISCSIOPT_DATA_SEQ_IN_ORDER,3537					    &options);3538	sess->pdu_inorder_en = test_bit(ISCSIOPT_DATA_PDU_IN_ORDER, &options);3539	sess->chap_auth_en = test_bit(ISCSIOPT_CHAP_AUTH_EN, &options);3540	conn->snack_req_en = test_bit(ISCSIOPT_SNACK_REQ_EN, &options);3541	sess->discovery_logout_en = test_bit(ISCSIOPT_DISCOVERY_LOGOUT_EN,3542					     &options);3543	sess->bidi_chap_en = test_bit(ISCSIOPT_BIDI_CHAP_EN, &options);3544	sess->discovery_auth_optional =3545			test_bit(ISCSIOPT_DISCOVERY_AUTH_OPTIONAL, &options);3546	if (test_bit(ISCSIOPT_ERL1, &options))3547		sess->erl |= BIT_1;3548	if (test_bit(ISCSIOPT_ERL0, &options))3549		sess->erl |= BIT_0;3550 3551	options = le16_to_cpu(fw_ddb_entry->tcp_options);3552	conn->tcp_timestamp_stat = test_bit(TCPOPT_TIMESTAMP_STAT, &options);3553	conn->tcp_nagle_disable = test_bit(TCPOPT_NAGLE_DISABLE, &options);3554	conn->tcp_wsf_disable = test_bit(TCPOPT_WSF_DISABLE, &options);3555	if (test_bit(TCPOPT_TIMER_SCALE3, &options))3556		conn->tcp_timer_scale |= BIT_3;3557	if (test_bit(TCPOPT_TIMER_SCALE2, &options))3558		conn->tcp_timer_scale |= BIT_2;3559	if (test_bit(TCPOPT_TIMER_SCALE1, &options))3560		conn->tcp_timer_scale |= BIT_1;3561 3562	conn->tcp_timer_scale >>= 1;3563	conn->tcp_timestamp_en = test_bit(TCPOPT_TIMESTAMP_EN, &options);3564 3565	options = le16_to_cpu(fw_ddb_entry->ip_options);3566	conn->fragment_disable = test_bit(IPOPT_FRAGMENT_DISABLE, &options);3567 3568	conn->max_recv_dlength = BYTE_UNITS *3569			  le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len);3570	conn->max_xmit_dlength = BYTE_UNITS *3571			  le16_to_cpu(fw_ddb_entry->iscsi_max_snd_data_seg_len);3572	sess->first_burst = BYTE_UNITS *3573			       le16_to_cpu(fw_ddb_entry->iscsi_first_burst_len);3574	sess->max_burst = BYTE_UNITS *3575				 le16_to_cpu(fw_ddb_entry->iscsi_max_burst_len);3576	sess->max_r2t = le16_to_cpu(fw_ddb_entry->iscsi_max_outsnd_r2t);3577	sess->time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);3578	sess->time2retain = le16_to_cpu(fw_ddb_entry->iscsi_def_time2retain);3579	sess->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);3580	conn->max_segment_size = le16_to_cpu(fw_ddb_entry->mss);3581	conn->tcp_xmit_wsf = fw_ddb_entry->tcp_xmt_wsf;3582	conn->tcp_recv_wsf = fw_ddb_entry->tcp_rcv_wsf;3583	conn->ipv6_flow_label = le16_to_cpu(fw_ddb_entry->ipv6_flow_lbl);3584	conn->keepalive_timeout = le16_to_cpu(fw_ddb_entry->ka_timeout);3585	conn->local_port = le16_to_cpu(fw_ddb_entry->lcl_port);3586	conn->statsn = le32_to_cpu(fw_ddb_entry->stat_sn);3587	conn->exp_statsn = le32_to_cpu(fw_ddb_entry->exp_stat_sn);3588	sess->discovery_parent_idx = le16_to_cpu(fw_ddb_entry->ddb_link);3589	sess->discovery_parent_type = le16_to_cpu(fw_ddb_entry->ddb_link);3590	sess->chap_out_idx = le16_to_cpu(fw_ddb_entry->chap_tbl_idx);3591	sess->tsid = le16_to_cpu(fw_ddb_entry->tsid);3592 3593	sess->default_taskmgmt_timeout =3594				le16_to_cpu(fw_ddb_entry->def_timeout);3595	conn->port = le16_to_cpu(fw_ddb_entry->port);3596 3597	options = le16_to_cpu(fw_ddb_entry->options);3598	conn->ipaddress = kzalloc(IPv6_ADDR_LEN, GFP_KERNEL);3599	if (!conn->ipaddress) {3600		rc = -ENOMEM;3601		goto exit_copy;3602	}3603 3604	conn->redirect_ipaddr = kzalloc(IPv6_ADDR_LEN, GFP_KERNEL);3605	if (!conn->redirect_ipaddr) {3606		rc = -ENOMEM;3607		goto exit_copy;3608	}3609 3610	memcpy(conn->ipaddress, fw_ddb_entry->ip_addr, IPv6_ADDR_LEN);3611	memcpy(conn->redirect_ipaddr, fw_ddb_entry->tgt_addr, IPv6_ADDR_LEN);3612 3613	if (test_bit(OPT_IPV6_DEVICE, &options)) {3614		conn->ipv6_traffic_class = fw_ddb_entry->ipv4_tos;3615 3616		conn->link_local_ipv6_addr = kmemdup(3617					fw_ddb_entry->link_local_ipv6_addr,3618					IPv6_ADDR_LEN, GFP_KERNEL);3619		if (!conn->link_local_ipv6_addr) {3620			rc = -ENOMEM;3621			goto exit_copy;3622		}3623	} else {3624		conn->ipv4_tos = fw_ddb_entry->ipv4_tos;3625	}3626 3627	if (fw_ddb_entry->iscsi_name[0]) {3628		rc = iscsi_switch_str_param(&sess->targetname,3629					    (char *)fw_ddb_entry->iscsi_name);3630		if (rc)3631			goto exit_copy;3632	}3633 3634	if (fw_ddb_entry->iscsi_alias[0]) {3635		rc = iscsi_switch_str_param(&sess->targetalias,3636					    (char *)fw_ddb_entry->iscsi_alias);3637		if (rc)3638			goto exit_copy;3639	}3640 3641	COPY_ISID(sess->isid, fw_ddb_entry->isid);3642 3643exit_copy:3644	return rc;3645}3646 3647static int qla4xxx_copy_to_fwddb_param(struct iscsi_bus_flash_session *sess,3648				       struct iscsi_bus_flash_conn *conn,3649				       struct dev_db_entry *fw_ddb_entry)3650{3651	uint16_t options;3652 3653	options = le16_to_cpu(fw_ddb_entry->options);3654	SET_BITVAL(conn->is_fw_assigned_ipv6,  options, BIT_11);3655	if (!strncmp(sess->portal_type, PORTAL_TYPE_IPV6, 4))3656		options |= BIT_8;3657	else3658		options &= ~BIT_8;3659 3660	SET_BITVAL(sess->auto_snd_tgt_disable, options, BIT_6);3661	SET_BITVAL(sess->discovery_sess, options, BIT_4);3662	SET_BITVAL(sess->entry_state, options, BIT_3);3663	fw_ddb_entry->options = cpu_to_le16(options);3664 3665	options = le16_to_cpu(fw_ddb_entry->iscsi_options);3666	SET_BITVAL(conn->hdrdgst_en, options, BIT_13);3667	SET_BITVAL(conn->datadgst_en, options, BIT_12);3668	SET_BITVAL(sess->imm_data_en, options, BIT_11);3669	SET_BITVAL(sess->initial_r2t_en, options, BIT_10);3670	SET_BITVAL(sess->dataseq_inorder_en, options, BIT_9);3671	SET_BITVAL(sess->pdu_inorder_en, options, BIT_8);3672	SET_BITVAL(sess->chap_auth_en, options, BIT_7);3673	SET_BITVAL(conn->snack_req_en, options, BIT_6);3674	SET_BITVAL(sess->discovery_logout_en, options, BIT_5);3675	SET_BITVAL(sess->bidi_chap_en, options, BIT_4);3676	SET_BITVAL(sess->discovery_auth_optional, options, BIT_3);3677	SET_BITVAL(sess->erl & BIT_1, options, BIT_1);3678	SET_BITVAL(sess->erl & BIT_0, options, BIT_0);3679	fw_ddb_entry->iscsi_options = cpu_to_le16(options);3680 3681	options = le16_to_cpu(fw_ddb_entry->tcp_options);3682	SET_BITVAL(conn->tcp_timestamp_stat, options, BIT_6);3683	SET_BITVAL(conn->tcp_nagle_disable, options, BIT_5);3684	SET_BITVAL(conn->tcp_wsf_disable, options, BIT_4);3685	SET_BITVAL(conn->tcp_timer_scale & BIT_2, options, BIT_3);3686	SET_BITVAL(conn->tcp_timer_scale & BIT_1, options, BIT_2);3687	SET_BITVAL(conn->tcp_timer_scale & BIT_0, options, BIT_1);3688	SET_BITVAL(conn->tcp_timestamp_en, options, BIT_0);3689	fw_ddb_entry->tcp_options = cpu_to_le16(options);3690 3691	options = le16_to_cpu(fw_ddb_entry->ip_options);3692	SET_BITVAL(conn->fragment_disable, options, BIT_4);3693	fw_ddb_entry->ip_options = cpu_to_le16(options);3694 3695	fw_ddb_entry->iscsi_max_outsnd_r2t = cpu_to_le16(sess->max_r2t);3696	fw_ddb_entry->iscsi_max_rcv_data_seg_len =3697			       cpu_to_le16(conn->max_recv_dlength / BYTE_UNITS);3698	fw_ddb_entry->iscsi_max_snd_data_seg_len =3699			       cpu_to_le16(conn->max_xmit_dlength / BYTE_UNITS);3700	fw_ddb_entry->iscsi_first_burst_len =3701				cpu_to_le16(sess->first_burst / BYTE_UNITS);3702	fw_ddb_entry->iscsi_max_burst_len = cpu_to_le16(sess->max_burst /3703					    BYTE_UNITS);3704	fw_ddb_entry->iscsi_def_time2wait = cpu_to_le16(sess->time2wait);3705	fw_ddb_entry->iscsi_def_time2retain = cpu_to_le16(sess->time2retain);3706	fw_ddb_entry->tgt_portal_grp = cpu_to_le16(sess->tpgt);3707	fw_ddb_entry->mss = cpu_to_le16(conn->max_segment_size);3708	fw_ddb_entry->tcp_xmt_wsf = (uint8_t) cpu_to_le32(conn->tcp_xmit_wsf);3709	fw_ddb_entry->tcp_rcv_wsf = (uint8_t) cpu_to_le32(conn->tcp_recv_wsf);3710	fw_ddb_entry->ipv6_flow_lbl = cpu_to_le16(conn->ipv6_flow_label);3711	fw_ddb_entry->ka_timeout = cpu_to_le16(conn->keepalive_timeout);3712	fw_ddb_entry->lcl_port = cpu_to_le16(conn->local_port);3713	fw_ddb_entry->stat_sn = cpu_to_le32(conn->statsn);3714	fw_ddb_entry->exp_stat_sn = cpu_to_le32(conn->exp_statsn);3715	fw_ddb_entry->ddb_link = cpu_to_le16(sess->discovery_parent_idx);3716	fw_ddb_entry->chap_tbl_idx = cpu_to_le16(sess->chap_out_idx);3717	fw_ddb_entry->tsid = cpu_to_le16(sess->tsid);3718	fw_ddb_entry->port = cpu_to_le16(conn->port);3719	fw_ddb_entry->def_timeout =3720				cpu_to_le16(sess->default_taskmgmt_timeout);3721 3722	if (!strncmp(sess->portal_type, PORTAL_TYPE_IPV6, 4))3723		fw_ddb_entry->ipv4_tos = conn->ipv6_traffic_class;3724	else3725		fw_ddb_entry->ipv4_tos = conn->ipv4_tos;3726 3727	if (conn->ipaddress)3728		memcpy(fw_ddb_entry->ip_addr, conn->ipaddress,3729		       sizeof(fw_ddb_entry->ip_addr));3730 3731	if (conn->redirect_ipaddr)3732		memcpy(fw_ddb_entry->tgt_addr, conn->redirect_ipaddr,3733		       sizeof(fw_ddb_entry->tgt_addr));3734 3735	if (conn->link_local_ipv6_addr)3736		memcpy(fw_ddb_entry->link_local_ipv6_addr,3737		       conn->link_local_ipv6_addr,3738		       sizeof(fw_ddb_entry->link_local_ipv6_addr));3739 3740	if (sess->targetname)3741		memcpy(fw_ddb_entry->iscsi_name, sess->targetname,3742		       sizeof(fw_ddb_entry->iscsi_name));3743 3744	if (sess->targetalias)3745		memcpy(fw_ddb_entry->iscsi_alias, sess->targetalias,3746		       sizeof(fw_ddb_entry->iscsi_alias));3747 3748	COPY_ISID(fw_ddb_entry->isid, sess->isid);3749 3750	return 0;3751}3752 3753static void qla4xxx_copy_to_sess_conn_params(struct iscsi_conn *conn,3754					     struct iscsi_session *sess,3755					     struct dev_db_entry *fw_ddb_entry)3756{3757	unsigned long options = 0;3758	uint16_t ddb_link;3759	uint16_t disc_parent;3760	char ip_addr[DDB_IPADDR_LEN];3761 3762	options = le16_to_cpu(fw_ddb_entry->options);3763	conn->is_fw_assigned_ipv6 = test_bit(OPT_IS_FW_ASSIGNED_IPV6, &options);3764	sess->auto_snd_tgt_disable = test_bit(OPT_AUTO_SENDTGTS_DISABLE,3765					      &options);3766	sess->discovery_sess = test_bit(OPT_DISC_SESSION, &options);3767 3768	options = le16_to_cpu(fw_ddb_entry->iscsi_options);3769	conn->hdrdgst_en = test_bit(ISCSIOPT_HEADER_DIGEST_EN, &options);3770	conn->datadgst_en = test_bit(ISCSIOPT_DATA_DIGEST_EN, &options);3771	sess->imm_data_en = test_bit(ISCSIOPT_IMMEDIATE_DATA_EN, &options);3772	sess->initial_r2t_en = test_bit(ISCSIOPT_INITIAL_R2T_EN, &options);3773	sess->dataseq_inorder_en = test_bit(ISCSIOPT_DATA_SEQ_IN_ORDER,3774					    &options);3775	sess->pdu_inorder_en = test_bit(ISCSIOPT_DATA_PDU_IN_ORDER, &options);3776	sess->chap_auth_en = test_bit(ISCSIOPT_CHAP_AUTH_EN, &options);3777	sess->discovery_logout_en = test_bit(ISCSIOPT_DISCOVERY_LOGOUT_EN,3778					     &options);3779	sess->bidi_chap_en = test_bit(ISCSIOPT_BIDI_CHAP_EN, &options);3780	sess->discovery_auth_optional =3781			test_bit(ISCSIOPT_DISCOVERY_AUTH_OPTIONAL, &options);3782	if (test_bit(ISCSIOPT_ERL1, &options))3783		sess->erl |= BIT_1;3784	if (test_bit(ISCSIOPT_ERL0, &options))3785		sess->erl |= BIT_0;3786 3787	options = le16_to_cpu(fw_ddb_entry->tcp_options);3788	conn->tcp_timestamp_stat = test_bit(TCPOPT_TIMESTAMP_STAT, &options);3789	conn->tcp_nagle_disable = test_bit(TCPOPT_NAGLE_DISABLE, &options);3790	conn->tcp_wsf_disable = test_bit(TCPOPT_WSF_DISABLE, &options);3791	if (test_bit(TCPOPT_TIMER_SCALE3, &options))3792		conn->tcp_timer_scale |= BIT_3;3793	if (test_bit(TCPOPT_TIMER_SCALE2, &options))3794		conn->tcp_timer_scale |= BIT_2;3795	if (test_bit(TCPOPT_TIMER_SCALE1, &options))3796		conn->tcp_timer_scale |= BIT_1;3797 3798	conn->tcp_timer_scale >>= 1;3799	conn->tcp_timestamp_en = test_bit(TCPOPT_TIMESTAMP_EN, &options);3800 3801	options = le16_to_cpu(fw_ddb_entry->ip_options);3802	conn->fragment_disable = test_bit(IPOPT_FRAGMENT_DISABLE, &options);3803 3804	conn->max_recv_dlength = BYTE_UNITS *3805			  le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len);3806	conn->max_xmit_dlength = BYTE_UNITS *3807			  le16_to_cpu(fw_ddb_entry->iscsi_max_snd_data_seg_len);3808	sess->max_r2t = le16_to_cpu(fw_ddb_entry->iscsi_max_outsnd_r2t);3809	sess->first_burst = BYTE_UNITS *3810			       le16_to_cpu(fw_ddb_entry->iscsi_first_burst_len);3811	sess->max_burst = BYTE_UNITS *3812				 le16_to_cpu(fw_ddb_entry->iscsi_max_burst_len);3813	sess->time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);3814	sess->time2retain = le16_to_cpu(fw_ddb_entry->iscsi_def_time2retain);3815	sess->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);3816	conn->max_segment_size = le16_to_cpu(fw_ddb_entry->mss);3817	conn->tcp_xmit_wsf = fw_ddb_entry->tcp_xmt_wsf;3818	conn->tcp_recv_wsf = fw_ddb_entry->tcp_rcv_wsf;3819	conn->ipv4_tos = fw_ddb_entry->ipv4_tos;3820	conn->keepalive_tmo = le16_to_cpu(fw_ddb_entry->ka_timeout);3821	conn->local_port = le16_to_cpu(fw_ddb_entry->lcl_port);3822	conn->statsn = le32_to_cpu(fw_ddb_entry->stat_sn);3823	conn->exp_statsn = le32_to_cpu(fw_ddb_entry->exp_stat_sn);3824	sess->tsid = le16_to_cpu(fw_ddb_entry->tsid);3825	COPY_ISID(sess->isid, fw_ddb_entry->isid);3826 3827	ddb_link = le16_to_cpu(fw_ddb_entry->ddb_link);3828	if (ddb_link == DDB_ISNS)3829		disc_parent = ISCSI_DISC_PARENT_ISNS;3830	else if (ddb_link == DDB_NO_LINK)3831		disc_parent = ISCSI_DISC_PARENT_UNKNOWN;3832	else if (ddb_link < MAX_DDB_ENTRIES)3833		disc_parent = ISCSI_DISC_PARENT_SENDTGT;3834	else3835		disc_parent = ISCSI_DISC_PARENT_UNKNOWN;3836 3837	iscsi_set_param(conn->cls_conn, ISCSI_PARAM_DISCOVERY_PARENT_TYPE,3838			iscsi_get_discovery_parent_name(disc_parent), 0);3839 3840	iscsi_set_param(conn->cls_conn, ISCSI_PARAM_TARGET_ALIAS,3841			(char *)fw_ddb_entry->iscsi_alias, 0);3842 3843	options = le16_to_cpu(fw_ddb_entry->options);3844	if (options & DDB_OPT_IPV6_DEVICE) {3845		memset(ip_addr, 0, sizeof(ip_addr));3846		sprintf(ip_addr, "%pI6", fw_ddb_entry->link_local_ipv6_addr);3847		iscsi_set_param(conn->cls_conn, ISCSI_PARAM_LOCAL_IPADDR,3848				(char *)ip_addr, 0);3849	}3850}3851 3852static void qla4xxx_copy_fwddb_param(struct scsi_qla_host *ha,3853				     struct dev_db_entry *fw_ddb_entry,3854				     struct iscsi_cls_session *cls_sess,3855				     struct iscsi_cls_conn *cls_conn)3856{3857	int buflen = 0;3858	struct iscsi_session *sess;3859	struct ddb_entry *ddb_entry;3860	struct ql4_chap_table chap_tbl;3861	struct iscsi_conn *conn;3862	char ip_addr[DDB_IPADDR_LEN];3863	uint16_t options = 0;3864 3865	sess = cls_sess->dd_data;3866	ddb_entry = sess->dd_data;3867	conn = cls_conn->dd_data;3868	memset(&chap_tbl, 0, sizeof(chap_tbl));3869 3870	ddb_entry->chap_tbl_idx = le16_to_cpu(fw_ddb_entry->chap_tbl_idx);3871 3872	qla4xxx_copy_to_sess_conn_params(conn, sess, fw_ddb_entry);3873 3874	sess->def_taskmgmt_tmo = le16_to_cpu(fw_ddb_entry->def_timeout);3875	conn->persistent_port = le16_to_cpu(fw_ddb_entry->port);3876 3877	memset(ip_addr, 0, sizeof(ip_addr));3878	options = le16_to_cpu(fw_ddb_entry->options);3879	if (options & DDB_OPT_IPV6_DEVICE) {3880		iscsi_set_param(cls_conn, ISCSI_PARAM_PORTAL_TYPE, "ipv6", 4);3881 3882		memset(ip_addr, 0, sizeof(ip_addr));3883		sprintf(ip_addr, "%pI6", fw_ddb_entry->ip_addr);3884	} else {3885		iscsi_set_param(cls_conn, ISCSI_PARAM_PORTAL_TYPE, "ipv4", 4);3886		sprintf(ip_addr, "%pI4", fw_ddb_entry->ip_addr);3887	}3888 3889	iscsi_set_param(cls_conn, ISCSI_PARAM_PERSISTENT_ADDRESS,3890			(char *)ip_addr, buflen);3891	iscsi_set_param(cls_conn, ISCSI_PARAM_TARGET_NAME,3892			(char *)fw_ddb_entry->iscsi_name, buflen);3893	iscsi_set_param(cls_conn, ISCSI_PARAM_INITIATOR_NAME,3894			(char *)ha->name_string, buflen);3895 3896	if (ddb_entry->chap_tbl_idx != INVALID_ENTRY) {3897		if (!qla4xxx_get_uni_chap_at_index(ha, chap_tbl.name,3898						   chap_tbl.secret,3899						   ddb_entry->chap_tbl_idx)) {3900			iscsi_set_param(cls_conn, ISCSI_PARAM_USERNAME,3901					(char *)chap_tbl.name,3902					strlen((char *)chap_tbl.name));3903			iscsi_set_param(cls_conn, ISCSI_PARAM_PASSWORD,3904					(char *)chap_tbl.secret,3905					chap_tbl.secret_len);3906		}3907	}3908}3909 3910void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha,3911					     struct ddb_entry *ddb_entry)3912{3913	struct iscsi_cls_session *cls_sess;3914	struct iscsi_cls_conn *cls_conn;3915	uint32_t ddb_state;3916	dma_addr_t fw_ddb_entry_dma;3917	struct dev_db_entry *fw_ddb_entry;3918 3919	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),3920					  &fw_ddb_entry_dma, GFP_KERNEL);3921	if (!fw_ddb_entry) {3922		ql4_printk(KERN_ERR, ha,3923			   "%s: Unable to allocate dma buffer\n", __func__);3924		goto exit_session_conn_fwddb_param;3925	}3926 3927	if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry,3928				    fw_ddb_entry_dma, NULL, NULL, &ddb_state,3929				    NULL, NULL, NULL) == QLA_ERROR) {3930		DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "3931				  "get_ddb_entry for fw_ddb_index %d\n",3932				  ha->host_no, __func__,3933				  ddb_entry->fw_ddb_index));3934		goto exit_session_conn_fwddb_param;3935	}3936 3937	cls_sess = ddb_entry->sess;3938 3939	cls_conn = ddb_entry->conn;3940 3941	/* Update params */3942	qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, cls_conn);3943 3944exit_session_conn_fwddb_param:3945	if (fw_ddb_entry)3946		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),3947				  fw_ddb_entry, fw_ddb_entry_dma);3948}3949 3950void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,3951				       struct ddb_entry *ddb_entry)3952{3953	struct iscsi_cls_session *cls_sess;3954	struct iscsi_cls_conn *cls_conn;3955	struct iscsi_session *sess;3956	struct iscsi_conn *conn;3957	uint32_t ddb_state;3958	dma_addr_t fw_ddb_entry_dma;3959	struct dev_db_entry *fw_ddb_entry;3960 3961	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),3962					  &fw_ddb_entry_dma, GFP_KERNEL);3963	if (!fw_ddb_entry) {3964		ql4_printk(KERN_ERR, ha,3965			   "%s: Unable to allocate dma buffer\n", __func__);3966		goto exit_session_conn_param;3967	}3968 3969	if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry,3970				    fw_ddb_entry_dma, NULL, NULL, &ddb_state,3971				    NULL, NULL, NULL) == QLA_ERROR) {3972		DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "3973				  "get_ddb_entry for fw_ddb_index %d\n",3974				  ha->host_no, __func__,3975				  ddb_entry->fw_ddb_index));3976		goto exit_session_conn_param;3977	}3978 3979	cls_sess = ddb_entry->sess;3980	sess = cls_sess->dd_data;3981 3982	cls_conn = ddb_entry->conn;3983	conn = cls_conn->dd_data;3984 3985	/* Update timers after login */3986	ddb_entry->default_relogin_timeout =3987		(le16_to_cpu(fw_ddb_entry->def_timeout) > LOGIN_TOV) &&3988		 (le16_to_cpu(fw_ddb_entry->def_timeout) < LOGIN_TOV * 10) ?3989		 le16_to_cpu(fw_ddb_entry->def_timeout) : LOGIN_TOV;3990	ddb_entry->default_time2wait =3991				le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);3992 3993	/* Update params */3994	ddb_entry->chap_tbl_idx = le16_to_cpu(fw_ddb_entry->chap_tbl_idx);3995	qla4xxx_copy_to_sess_conn_params(conn, sess, fw_ddb_entry);3996 3997	memcpy(sess->initiatorname, ha->name_string,3998	       min(sizeof(ha->name_string), sizeof(sess->initiatorname)));3999 4000exit_session_conn_param:4001	if (fw_ddb_entry)4002		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),4003				  fw_ddb_entry, fw_ddb_entry_dma);4004}4005 4006/*4007 * Timer routines4008 */4009static void qla4xxx_timer(struct timer_list *t);4010 4011static void qla4xxx_start_timer(struct scsi_qla_host *ha,4012				unsigned long interval)4013{4014	DEBUG(printk("scsi: %s: Starting timer thread for adapter %d\n",4015		     __func__, ha->host->host_no));4016	timer_setup(&ha->timer, qla4xxx_timer, 0);4017	ha->timer.expires = jiffies + interval * HZ;4018	add_timer(&ha->timer);4019	ha->timer_active = 1;4020}4021 4022static void qla4xxx_stop_timer(struct scsi_qla_host *ha)4023{4024	del_timer_sync(&ha->timer);4025	ha->timer_active = 0;4026}4027 4028/***4029 * qla4xxx_mark_device_missing - blocks the session4030 * @cls_session: Pointer to the session to be blocked4031 * @ddb_entry: Pointer to device database entry4032 *4033 * This routine marks a device missing and close connection.4034 **/4035void qla4xxx_mark_device_missing(struct iscsi_cls_session *cls_session)4036{4037	iscsi_block_session(cls_session);4038}4039 4040/**4041 * qla4xxx_mark_all_devices_missing - mark all devices as missing.4042 * @ha: Pointer to host adapter structure.4043 *4044 * This routine marks a device missing and resets the relogin retry count.4045 **/4046void qla4xxx_mark_all_devices_missing(struct scsi_qla_host *ha)4047{4048	iscsi_host_for_each_session(ha->host, qla4xxx_mark_device_missing);4049}4050 4051static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha,4052				       struct ddb_entry *ddb_entry,4053				       struct scsi_cmnd *cmd)4054{4055	struct srb *srb;4056 4057	srb = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);4058	if (!srb)4059		return srb;4060 4061	kref_init(&srb->srb_ref);4062	srb->ha = ha;4063	srb->ddb = ddb_entry;4064	srb->cmd = cmd;4065	srb->flags = 0;4066	qla4xxx_cmd_priv(cmd)->srb = srb;4067 4068	return srb;4069}4070 4071static void qla4xxx_srb_free_dma(struct scsi_qla_host *ha, struct srb *srb)4072{4073	struct scsi_cmnd *cmd = srb->cmd;4074 4075	if (srb->flags & SRB_DMA_VALID) {4076		scsi_dma_unmap(cmd);4077		srb->flags &= ~SRB_DMA_VALID;4078	}4079	qla4xxx_cmd_priv(cmd)->srb = NULL;4080}4081 4082void qla4xxx_srb_compl(struct kref *ref)4083{4084	struct srb *srb = container_of(ref, struct srb, srb_ref);4085	struct scsi_cmnd *cmd = srb->cmd;4086	struct scsi_qla_host *ha = srb->ha;4087 4088	qla4xxx_srb_free_dma(ha, srb);4089 4090	mempool_free(srb, ha->srb_mempool);4091 4092	scsi_done(cmd);4093}4094 4095/**4096 * qla4xxx_queuecommand - scsi layer issues scsi command to driver.4097 * @host: scsi host4098 * @cmd: Pointer to Linux's SCSI command structure4099 *4100 * Remarks:4101 * This routine is invoked by Linux to send a SCSI command to the driver.4102 * The mid-level driver tries to ensure that queuecommand never gets4103 * invoked concurrently with itself or the interrupt handler (although4104 * the interrupt handler may call this routine as part of request-4105 * completion handling).   Unfortunely, it sometimes calls the scheduler4106 * in interrupt context which is a big NO! NO!.4107 **/4108static int qla4xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)4109{4110	struct scsi_qla_host *ha = to_qla_host(host);4111	struct ddb_entry *ddb_entry = cmd->device->hostdata;4112	struct iscsi_cls_session *sess = ddb_entry->sess;4113	struct srb *srb;4114	int rval;4115 4116	if (test_bit(AF_EEH_BUSY, &ha->flags)) {4117		if (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))4118			cmd->result = DID_NO_CONNECT << 16;4119		else4120			cmd->result = DID_REQUEUE << 16;4121		goto qc_fail_command;4122	}4123 4124	if (!sess) {4125		cmd->result = DID_IMM_RETRY << 16;4126		goto qc_fail_command;4127	}4128 4129	rval = iscsi_session_chkready(sess);4130	if (rval) {4131		cmd->result = rval;4132		goto qc_fail_command;4133	}4134 4135	if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||4136	    test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||4137	    test_bit(DPC_RESET_HA, &ha->dpc_flags) ||4138	    test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags) ||4139	    test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags) ||4140	    !test_bit(AF_ONLINE, &ha->flags) ||4141	    !test_bit(AF_LINK_UP, &ha->flags) ||4142	    test_bit(AF_LOOPBACK, &ha->flags) ||4143	    test_bit(DPC_POST_IDC_ACK, &ha->dpc_flags) ||4144	    test_bit(DPC_RESTORE_ACB, &ha->dpc_flags) ||4145	    test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))4146		goto qc_host_busy;4147 4148	srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd);4149	if (!srb)4150		goto qc_host_busy;4151 4152	rval = qla4xxx_send_command_to_isp(ha, srb);4153	if (rval != QLA_SUCCESS)4154		goto qc_host_busy_free_sp;4155 4156	return 0;4157 4158qc_host_busy_free_sp:4159	qla4xxx_srb_free_dma(ha, srb);4160	mempool_free(srb, ha->srb_mempool);4161 4162qc_host_busy:4163	return SCSI_MLQUEUE_HOST_BUSY;4164 4165qc_fail_command:4166	scsi_done(cmd);4167 4168	return 0;4169}4170 4171/**4172 * qla4xxx_mem_free - frees memory allocated to adapter4173 * @ha: Pointer to host adapter structure.4174 *4175 * Frees memory previously allocated by qla4xxx_mem_alloc4176 **/4177static void qla4xxx_mem_free(struct scsi_qla_host *ha)4178{4179	if (ha->queues)4180		dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues,4181				  ha->queues_dma);4182 4183	vfree(ha->fw_dump);4184 4185	ha->queues_len = 0;4186	ha->queues = NULL;4187	ha->queues_dma = 0;4188	ha->request_ring = NULL;4189	ha->request_dma = 0;4190	ha->response_ring = NULL;4191	ha->response_dma = 0;4192	ha->shadow_regs = NULL;4193	ha->shadow_regs_dma = 0;4194	ha->fw_dump = NULL;4195	ha->fw_dump_size = 0;4196 4197	/* Free srb pool. */4198	mempool_destroy(ha->srb_mempool);4199	ha->srb_mempool = NULL;4200 4201	dma_pool_destroy(ha->chap_dma_pool);4202 4203	vfree(ha->chap_list);4204	ha->chap_list = NULL;4205 4206	dma_pool_destroy(ha->fw_ddb_dma_pool);4207 4208	/* release io space registers  */4209	if (is_qla8022(ha)) {4210		if (ha->nx_pcibase)4211			iounmap(4212			    (struct device_reg_82xx __iomem *)ha->nx_pcibase);4213	} else if (is_qla8032(ha) || is_qla8042(ha)) {4214		if (ha->nx_pcibase)4215			iounmap(4216			    (struct device_reg_83xx __iomem *)ha->nx_pcibase);4217	} else if (ha->reg) {4218		iounmap(ha->reg);4219	}4220 4221	vfree(ha->reset_tmplt.buff);4222 4223	pci_release_regions(ha->pdev);4224}4225 4226/**4227 * qla4xxx_mem_alloc - allocates memory for use by adapter.4228 * @ha: Pointer to host adapter structure4229 *4230 * Allocates DMA memory for request and response queues. Also allocates memory4231 * for srbs.4232 **/4233static int qla4xxx_mem_alloc(struct scsi_qla_host *ha)4234{4235	unsigned long align;4236 4237	/* Allocate contiguous block of DMA memory for queues. */4238	ha->queues_len = ((REQUEST_QUEUE_DEPTH * QUEUE_SIZE) +4239			  (RESPONSE_QUEUE_DEPTH * QUEUE_SIZE) +4240			  sizeof(struct shadow_regs) +4241			  MEM_ALIGN_VALUE +4242			  (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);4243	ha->queues = dma_alloc_coherent(&ha->pdev->dev, ha->queues_len,4244					&ha->queues_dma, GFP_KERNEL);4245	if (ha->queues == NULL) {4246		ql4_printk(KERN_WARNING, ha,4247		    "Memory Allocation failed - queues.\n");4248 4249		goto mem_alloc_error_exit;4250	}4251 4252	/*4253	 * As per RISC alignment requirements -- the bus-address must be a4254	 * multiple of the request-ring size (in bytes).4255	 */4256	align = 0;4257	if ((unsigned long)ha->queues_dma & (MEM_ALIGN_VALUE - 1))4258		align = MEM_ALIGN_VALUE - ((unsigned long)ha->queues_dma &4259					   (MEM_ALIGN_VALUE - 1));4260 4261	/* Update request and response queue pointers. */4262	ha->request_dma = ha->queues_dma + align;4263	ha->request_ring = (struct queue_entry *) (ha->queues + align);4264	ha->response_dma = ha->queues_dma + align +4265		(REQUEST_QUEUE_DEPTH * QUEUE_SIZE);4266	ha->response_ring = (struct queue_entry *) (ha->queues + align +4267						    (REQUEST_QUEUE_DEPTH *4268						     QUEUE_SIZE));4269	ha->shadow_regs_dma = ha->queues_dma + align +4270		(REQUEST_QUEUE_DEPTH * QUEUE_SIZE) +4271		(RESPONSE_QUEUE_DEPTH * QUEUE_SIZE);4272	ha->shadow_regs = (struct shadow_regs *) (ha->queues + align +4273						  (REQUEST_QUEUE_DEPTH *4274						   QUEUE_SIZE) +4275						  (RESPONSE_QUEUE_DEPTH *4276						   QUEUE_SIZE));4277 4278	/* Allocate memory for srb pool. */4279	ha->srb_mempool = mempool_create(SRB_MIN_REQ, mempool_alloc_slab,4280					 mempool_free_slab, srb_cachep);4281	if (ha->srb_mempool == NULL) {4282		ql4_printk(KERN_WARNING, ha,4283		    "Memory Allocation failed - SRB Pool.\n");4284 4285		goto mem_alloc_error_exit;4286	}4287 4288	ha->chap_dma_pool = dma_pool_create("ql4_chap", &ha->pdev->dev,4289					    CHAP_DMA_BLOCK_SIZE, 8, 0);4290 4291	if (ha->chap_dma_pool == NULL) {4292		ql4_printk(KERN_WARNING, ha,4293		    "%s: chap_dma_pool allocation failed..\n", __func__);4294		goto mem_alloc_error_exit;4295	}4296 4297	ha->fw_ddb_dma_pool = dma_pool_create("ql4_fw_ddb", &ha->pdev->dev,4298					      DDB_DMA_BLOCK_SIZE, 8, 0);4299 4300	if (ha->fw_ddb_dma_pool == NULL) {4301		ql4_printk(KERN_WARNING, ha,4302			   "%s: fw_ddb_dma_pool allocation failed..\n",4303			   __func__);4304		goto mem_alloc_error_exit;4305	}4306 4307	return QLA_SUCCESS;4308 4309mem_alloc_error_exit:4310	return QLA_ERROR;4311}4312 4313/**4314 * qla4_8xxx_check_temp - Check the ISP82XX temperature.4315 * @ha: adapter block pointer.4316 *4317 * Note: The caller should not hold the idc lock.4318 **/4319static int qla4_8xxx_check_temp(struct scsi_qla_host *ha)4320{4321	uint32_t temp, temp_state, temp_val;4322	int status = QLA_SUCCESS;4323 4324	temp = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_TEMP_STATE);4325 4326	temp_state = qla82xx_get_temp_state(temp);4327	temp_val = qla82xx_get_temp_val(temp);4328 4329	if (temp_state == QLA82XX_TEMP_PANIC) {4330		ql4_printk(KERN_WARNING, ha, "Device temperature %d degrees C"4331			   " exceeds maximum allowed. Hardware has been shut"4332			   " down.\n", temp_val);4333		status = QLA_ERROR;4334	} else if (temp_state == QLA82XX_TEMP_WARN) {4335		if (ha->temperature == QLA82XX_TEMP_NORMAL)4336			ql4_printk(KERN_WARNING, ha, "Device temperature %d"4337				   " degrees C exceeds operating range."4338				   " Immediate action needed.\n", temp_val);4339	} else {4340		if (ha->temperature == QLA82XX_TEMP_WARN)4341			ql4_printk(KERN_INFO, ha, "Device temperature is"4342				   " now %d degrees C in normal range.\n",4343				   temp_val);4344	}4345	ha->temperature = temp_state;4346	return status;4347}4348 4349/**4350 * qla4_8xxx_check_fw_alive  - Check firmware health4351 * @ha: Pointer to host adapter structure.4352 *4353 * Context: Interrupt4354 **/4355static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)4356{4357	uint32_t fw_heartbeat_counter;4358	int status = QLA_SUCCESS;4359 4360	fw_heartbeat_counter = qla4_8xxx_rd_direct(ha,4361						   QLA8XXX_PEG_ALIVE_COUNTER);4362	/* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */4363	if (fw_heartbeat_counter == 0xffffffff) {4364		DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Device in frozen "4365		    "state, QLA82XX_PEG_ALIVE_COUNTER is 0xffffffff\n",4366		    ha->host_no, __func__));4367		return status;4368	}4369 4370	if (ha->fw_heartbeat_counter == fw_heartbeat_counter) {4371		ha->seconds_since_last_heartbeat++;4372		/* FW not alive after 2 seconds */4373		if (ha->seconds_since_last_heartbeat == 2) {4374			ha->seconds_since_last_heartbeat = 0;4375			qla4_8xxx_dump_peg_reg(ha);4376			status = QLA_ERROR;4377		}4378	} else4379		ha->seconds_since_last_heartbeat = 0;4380 4381	ha->fw_heartbeat_counter = fw_heartbeat_counter;4382	return status;4383}4384 4385static void qla4_8xxx_process_fw_error(struct scsi_qla_host *ha)4386{4387	uint32_t halt_status;4388	int halt_status_unrecoverable = 0;4389 4390	halt_status = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_HALT_STATUS1);4391 4392	if (is_qla8022(ha)) {4393		ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n",4394			   __func__);4395		qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,4396				CRB_NIU_XG_PAUSE_CTL_P0 |4397				CRB_NIU_XG_PAUSE_CTL_P1);4398 4399		if (QLA82XX_FWERROR_CODE(halt_status) == 0x67)4400			ql4_printk(KERN_ERR, ha, "%s: Firmware aborted with error code 0x00006700. Device is being reset\n",4401				   __func__);4402		if (halt_status & HALT_STATUS_UNRECOVERABLE)4403			halt_status_unrecoverable = 1;4404	} else if (is_qla8032(ha) || is_qla8042(ha)) {4405		if (halt_status & QLA83XX_HALT_STATUS_FW_RESET)4406			ql4_printk(KERN_ERR, ha, "%s: Firmware error detected device is being reset\n",4407				   __func__);4408		else if (halt_status & QLA83XX_HALT_STATUS_UNRECOVERABLE)4409			halt_status_unrecoverable = 1;4410	}4411 4412	/*4413	 * Since we cannot change dev_state in interrupt context,4414	 * set appropriate DPC flag then wakeup DPC4415	 */4416	if (halt_status_unrecoverable) {4417		set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);4418	} else {4419		ql4_printk(KERN_INFO, ha, "%s: detect abort needed!\n",4420			   __func__);4421		set_bit(DPC_RESET_HA, &ha->dpc_flags);4422	}4423	qla4xxx_mailbox_premature_completion(ha);4424	qla4xxx_wake_dpc(ha);4425}4426 4427/**4428 * qla4_8xxx_watchdog - Poll dev state4429 * @ha: Pointer to host adapter structure.4430 *4431 * Context: Interrupt4432 **/4433void qla4_8xxx_watchdog(struct scsi_qla_host *ha)4434{4435	uint32_t dev_state;4436	uint32_t idc_ctrl;4437 4438	if (is_qla8032(ha) &&4439	    (qla4_83xx_is_detached(ha) == QLA_SUCCESS))4440		WARN_ONCE(1, "%s: iSCSI function %d marked invisible\n",4441			  __func__, ha->func_num);4442 4443	/* don't poll if reset is going on */4444	if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||4445	    test_bit(DPC_RESET_HA, &ha->dpc_flags) ||4446	    test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags))) {4447		dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);4448 4449		if (qla4_8xxx_check_temp(ha)) {4450			if (is_qla8022(ha)) {4451				ql4_printk(KERN_INFO, ha, "disabling pause transmit on port 0 & 1.\n");4452				qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,4453						CRB_NIU_XG_PAUSE_CTL_P0 |4454						CRB_NIU_XG_PAUSE_CTL_P1);4455			}4456			set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);4457			qla4xxx_wake_dpc(ha);4458		} else if (dev_state == QLA8XXX_DEV_NEED_RESET &&4459			   !test_bit(DPC_RESET_HA, &ha->dpc_flags)) {4460 4461			ql4_printk(KERN_INFO, ha, "%s: HW State: NEED RESET!\n",4462				   __func__);4463 4464			if (is_qla8032(ha) || is_qla8042(ha)) {4465				idc_ctrl = qla4_83xx_rd_reg(ha,4466							QLA83XX_IDC_DRV_CTRL);4467				if (!(idc_ctrl & GRACEFUL_RESET_BIT1)) {4468					ql4_printk(KERN_INFO, ha, "%s: Graceful reset bit is not set\n",4469						   __func__);4470					qla4xxx_mailbox_premature_completion(4471									    ha);4472				}4473			}4474 4475			if ((is_qla8032(ha) || is_qla8042(ha)) ||4476			    (is_qla8022(ha) && !ql4xdontresethba)) {4477				set_bit(DPC_RESET_HA, &ha->dpc_flags);4478				qla4xxx_wake_dpc(ha);4479			}4480		} else if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT &&4481		    !test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) {4482			ql4_printk(KERN_INFO, ha, "%s: HW State: NEED QUIES!\n",4483			    __func__);4484			set_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags);4485			qla4xxx_wake_dpc(ha);4486		} else  {4487			/* Check firmware health */4488			if (qla4_8xxx_check_fw_alive(ha))4489				qla4_8xxx_process_fw_error(ha);4490		}4491	}4492}4493 4494static void qla4xxx_check_relogin_flash_ddb(struct iscsi_cls_session *cls_sess)4495{4496	struct iscsi_session *sess;4497	struct ddb_entry *ddb_entry;4498	struct scsi_qla_host *ha;4499 4500	sess = cls_sess->dd_data;4501	ddb_entry = sess->dd_data;4502	ha = ddb_entry->ha;4503 4504	if (!(ddb_entry->ddb_type == FLASH_DDB))4505		return;4506 4507	if (adapter_up(ha) && !test_bit(DF_RELOGIN, &ddb_entry->flags) &&4508	    !iscsi_is_session_online(cls_sess)) {4509		if (atomic_read(&ddb_entry->retry_relogin_timer) !=4510		    INVALID_ENTRY) {4511			if (atomic_read(&ddb_entry->retry_relogin_timer) ==4512					0) {4513				atomic_set(&ddb_entry->retry_relogin_timer,4514					   INVALID_ENTRY);4515				set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);4516				set_bit(DF_RELOGIN, &ddb_entry->flags);4517				DEBUG2(ql4_printk(KERN_INFO, ha,4518				       "%s: index [%d] login device\n",4519					__func__, ddb_entry->fw_ddb_index));4520			} else4521				atomic_dec(&ddb_entry->retry_relogin_timer);4522		}4523	}4524 4525	/* Wait for relogin to timeout */4526	if (atomic_read(&ddb_entry->relogin_timer) &&4527	    (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) {4528		/*4529		 * If the relogin times out and the device is4530		 * still NOT ONLINE then try and relogin again.4531		 */4532		if (!iscsi_is_session_online(cls_sess)) {4533			/* Reset retry relogin timer */4534			atomic_inc(&ddb_entry->relogin_retry_count);4535			DEBUG2(ql4_printk(KERN_INFO, ha,4536				"%s: index[%d] relogin timed out-retrying"4537				" relogin (%d), retry (%d)\n", __func__,4538				ddb_entry->fw_ddb_index,4539				atomic_read(&ddb_entry->relogin_retry_count),4540				ddb_entry->default_time2wait + 4));4541			set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);4542			atomic_set(&ddb_entry->retry_relogin_timer,4543				   ddb_entry->default_time2wait + 4);4544		}4545	}4546}4547 4548/**4549 * qla4xxx_timer - checks every second for work to do.4550 * @t: Context to obtain pointer to host adapter structure.4551 **/4552static void qla4xxx_timer(struct timer_list *t)4553{4554	struct scsi_qla_host *ha = from_timer(ha, t, timer);4555	int start_dpc = 0;4556	uint16_t w;4557 4558	iscsi_host_for_each_session(ha->host, qla4xxx_check_relogin_flash_ddb);4559 4560	/* If we are in the middle of AER/EEH processing4561	 * skip any processing and reschedule the timer4562	 */4563	if (test_bit(AF_EEH_BUSY, &ha->flags)) {4564		mod_timer(&ha->timer, jiffies + HZ);4565		return;4566	}4567 4568	/* Hardware read to trigger an EEH error during mailbox waits. */4569	if (!pci_channel_offline(ha->pdev))4570		pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);4571 4572	if (is_qla80XX(ha))4573		qla4_8xxx_watchdog(ha);4574 4575	if (is_qla40XX(ha)) {4576		/* Check for heartbeat interval. */4577		if (ha->firmware_options & FWOPT_HEARTBEAT_ENABLE &&4578		    ha->heartbeat_interval != 0) {4579			ha->seconds_since_last_heartbeat++;4580			if (ha->seconds_since_last_heartbeat >4581			    ha->heartbeat_interval + 2)4582				set_bit(DPC_RESET_HA, &ha->dpc_flags);4583		}4584	}4585 4586	/* Process any deferred work. */4587	if (!list_empty(&ha->work_list))4588		start_dpc++;4589 4590	/* Wakeup the dpc routine for this adapter, if needed. */4591	if (start_dpc ||4592	     test_bit(DPC_RESET_HA, &ha->dpc_flags) ||4593	     test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags) ||4594	     test_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags) ||4595	     test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags) ||4596	     test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||4597	     test_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags) ||4598	     test_bit(DPC_LINK_CHANGED, &ha->dpc_flags) ||4599	     test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags) ||4600	     test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags) ||4601	     test_bit(DPC_SYSFS_DDB_EXPORT, &ha->dpc_flags) ||4602	     test_bit(DPC_AEN, &ha->dpc_flags)) {4603		DEBUG2(printk("scsi%ld: %s: scheduling dpc routine"4604			      " - dpc flags = 0x%lx\n",4605			      ha->host_no, __func__, ha->dpc_flags));4606		qla4xxx_wake_dpc(ha);4607	}4608 4609	/* Reschedule timer thread to call us back in one second */4610	mod_timer(&ha->timer, jiffies + HZ);4611 4612	DEBUG2(ha->seconds_since_last_intr++);4613}4614 4615/**4616 * qla4xxx_cmd_wait - waits for all outstanding commands to complete4617 * @ha: Pointer to host adapter structure.4618 *4619 * This routine stalls the driver until all outstanding commands are returned.4620 * Caller must release the Hardware Lock prior to calling this routine.4621 **/4622static int qla4xxx_cmd_wait(struct scsi_qla_host *ha)4623{4624	uint32_t index = 0;4625	unsigned long flags;4626	struct scsi_cmnd *cmd;4627	unsigned long wtime;4628	uint32_t wtmo;4629 4630	if (is_qla40XX(ha))4631		wtmo = WAIT_CMD_TOV;4632	else4633		wtmo = ha->nx_reset_timeout / 2;4634 4635	wtime = jiffies + (wtmo * HZ);4636 4637	DEBUG2(ql4_printk(KERN_INFO, ha,4638			  "Wait up to %u seconds for cmds to complete\n",4639			  wtmo));4640 4641	while (!time_after_eq(jiffies, wtime)) {4642		spin_lock_irqsave(&ha->hardware_lock, flags);4643		/* Find a command that hasn't completed. */4644		for (index = 0; index < ha->host->can_queue; index++) {4645			cmd = scsi_host_find_tag(ha->host, index);4646			/*4647			 * We cannot just check if the index is valid,4648			 * becase if we are run from the scsi eh, then4649			 * the scsi/block layer is going to prevent4650			 * the tag from being released.4651			 */4652			if (cmd != NULL && qla4xxx_cmd_priv(cmd)->srb)4653				break;4654		}4655		spin_unlock_irqrestore(&ha->hardware_lock, flags);4656 4657		/* If No Commands are pending, wait is complete */4658		if (index == ha->host->can_queue)4659			return QLA_SUCCESS;4660 4661		msleep(1000);4662	}4663	/* If we timed out on waiting for commands to come back4664	 * return ERROR. */4665	return QLA_ERROR;4666}4667 4668int qla4xxx_hw_reset(struct scsi_qla_host *ha)4669{4670	uint32_t ctrl_status;4671	unsigned long flags = 0;4672 4673	DEBUG2(printk(KERN_ERR "scsi%ld: %s\n", ha->host_no, __func__));4674 4675	if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS)4676		return QLA_ERROR;4677 4678	spin_lock_irqsave(&ha->hardware_lock, flags);4679 4680	/*4681	 * If the SCSI Reset Interrupt bit is set, clear it.4682	 * Otherwise, the Soft Reset won't work.4683	 */4684	ctrl_status = readw(&ha->reg->ctrl_status);4685	if ((ctrl_status & CSR_SCSI_RESET_INTR) != 0)4686		writel(set_rmask(CSR_SCSI_RESET_INTR), &ha->reg->ctrl_status);4687 4688	/* Issue Soft Reset */4689	writel(set_rmask(CSR_SOFT_RESET), &ha->reg->ctrl_status);4690	readl(&ha->reg->ctrl_status);4691 4692	spin_unlock_irqrestore(&ha->hardware_lock, flags);4693	return QLA_SUCCESS;4694}4695 4696/**4697 * qla4xxx_soft_reset - performs soft reset.4698 * @ha: Pointer to host adapter structure.4699 **/4700int qla4xxx_soft_reset(struct scsi_qla_host *ha)4701{4702	uint32_t max_wait_time;4703	unsigned long flags = 0;4704	int status;4705	uint32_t ctrl_status;4706 4707	status = qla4xxx_hw_reset(ha);4708	if (status != QLA_SUCCESS)4709		return status;4710 4711	status = QLA_ERROR;4712	/* Wait until the Network Reset Intr bit is cleared */4713	max_wait_time = RESET_INTR_TOV;4714	do {4715		spin_lock_irqsave(&ha->hardware_lock, flags);4716		ctrl_status = readw(&ha->reg->ctrl_status);4717		spin_unlock_irqrestore(&ha->hardware_lock, flags);4718 4719		if ((ctrl_status & CSR_NET_RESET_INTR) == 0)4720			break;4721 4722		msleep(1000);4723	} while ((--max_wait_time));4724 4725	if ((ctrl_status & CSR_NET_RESET_INTR) != 0) {4726		DEBUG2(printk(KERN_WARNING4727			      "scsi%ld: Network Reset Intr not cleared by "4728			      "Network function, clearing it now!\n",4729			      ha->host_no));4730		spin_lock_irqsave(&ha->hardware_lock, flags);4731		writel(set_rmask(CSR_NET_RESET_INTR), &ha->reg->ctrl_status);4732		readl(&ha->reg->ctrl_status);4733		spin_unlock_irqrestore(&ha->hardware_lock, flags);4734	}4735 4736	/* Wait until the firmware tells us the Soft Reset is done */4737	max_wait_time = SOFT_RESET_TOV;4738	do {4739		spin_lock_irqsave(&ha->hardware_lock, flags);4740		ctrl_status = readw(&ha->reg->ctrl_status);4741		spin_unlock_irqrestore(&ha->hardware_lock, flags);4742 4743		if ((ctrl_status & CSR_SOFT_RESET) == 0) {4744			status = QLA_SUCCESS;4745			break;4746		}4747 4748		msleep(1000);4749	} while ((--max_wait_time));4750 4751	/*4752	 * Also, make sure that the SCSI Reset Interrupt bit has been cleared4753	 * after the soft reset has taken place.4754	 */4755	spin_lock_irqsave(&ha->hardware_lock, flags);4756	ctrl_status = readw(&ha->reg->ctrl_status);4757	if ((ctrl_status & CSR_SCSI_RESET_INTR) != 0) {4758		writel(set_rmask(CSR_SCSI_RESET_INTR), &ha->reg->ctrl_status);4759		readl(&ha->reg->ctrl_status);4760	}4761	spin_unlock_irqrestore(&ha->hardware_lock, flags);4762 4763	/* If soft reset fails then most probably the bios on other4764	 * function is also enabled.4765	 * Since the initialization is sequential the other fn4766	 * wont be able to acknowledge the soft reset.4767	 * Issue a force soft reset to workaround this scenario.4768	 */4769	if (max_wait_time == 0) {4770		/* Issue Force Soft Reset */4771		spin_lock_irqsave(&ha->hardware_lock, flags);4772		writel(set_rmask(CSR_FORCE_SOFT_RESET), &ha->reg->ctrl_status);4773		readl(&ha->reg->ctrl_status);4774		spin_unlock_irqrestore(&ha->hardware_lock, flags);4775		/* Wait until the firmware tells us the Soft Reset is done */4776		max_wait_time = SOFT_RESET_TOV;4777		do {4778			spin_lock_irqsave(&ha->hardware_lock, flags);4779			ctrl_status = readw(&ha->reg->ctrl_status);4780			spin_unlock_irqrestore(&ha->hardware_lock, flags);4781 4782			if ((ctrl_status & CSR_FORCE_SOFT_RESET) == 0) {4783				status = QLA_SUCCESS;4784				break;4785			}4786 4787			msleep(1000);4788		} while ((--max_wait_time));4789	}4790 4791	return status;4792}4793 4794/**4795 * qla4xxx_abort_active_cmds - returns all outstanding i/o requests to O.S.4796 * @ha: Pointer to host adapter structure.4797 * @res: returned scsi status4798 *4799 * This routine is called just prior to a HARD RESET to return all4800 * outstanding commands back to the Operating System.4801 * Caller should make sure that the following locks are released4802 * before this calling routine: Hardware lock, and io_request_lock.4803 **/4804static void qla4xxx_abort_active_cmds(struct scsi_qla_host *ha, int res)4805{4806	struct srb *srb;4807	int i;4808	unsigned long flags;4809 4810	spin_lock_irqsave(&ha->hardware_lock, flags);4811	for (i = 0; i < ha->host->can_queue; i++) {4812		srb = qla4xxx_del_from_active_array(ha, i);4813		if (srb != NULL) {4814			srb->cmd->result = res;4815			kref_put(&srb->srb_ref, qla4xxx_srb_compl);4816		}4817	}4818	spin_unlock_irqrestore(&ha->hardware_lock, flags);4819}4820 4821void qla4xxx_dead_adapter_cleanup(struct scsi_qla_host *ha)4822{4823	clear_bit(AF_ONLINE, &ha->flags);4824 4825	/* Disable the board */4826	ql4_printk(KERN_INFO, ha, "Disabling the board\n");4827 4828	qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16);4829	qla4xxx_mark_all_devices_missing(ha);4830	clear_bit(AF_INIT_DONE, &ha->flags);4831}4832 4833static void qla4xxx_fail_session(struct iscsi_cls_session *cls_session)4834{4835	struct iscsi_session *sess;4836	struct ddb_entry *ddb_entry;4837 4838	sess = cls_session->dd_data;4839	ddb_entry = sess->dd_data;4840	ddb_entry->fw_ddb_device_state = DDB_DS_SESSION_FAILED;4841 4842	if (ddb_entry->ddb_type == FLASH_DDB)4843		iscsi_block_session(ddb_entry->sess);4844	else4845		iscsi_session_failure(cls_session->dd_data,4846				      ISCSI_ERR_CONN_FAILED);4847}4848 4849/**4850 * qla4xxx_recover_adapter - recovers adapter after a fatal error4851 * @ha: Pointer to host adapter structure.4852 **/4853static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)4854{4855	int status = QLA_ERROR;4856	uint8_t reset_chip = 0;4857	uint32_t dev_state;4858	unsigned long wait;4859 4860	/* Stall incoming I/O until we are done */4861	scsi_block_requests(ha->host);4862	clear_bit(AF_ONLINE, &ha->flags);4863	clear_bit(AF_LINK_UP, &ha->flags);4864 4865	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: adapter OFFLINE\n", __func__));4866 4867	set_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);4868 4869	if ((is_qla8032(ha) || is_qla8042(ha)) &&4870	    !test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) {4871		ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n",4872			   __func__);4873		/* disable pause frame for ISP83xx */4874		qla4_83xx_disable_pause(ha);4875	}4876 4877	iscsi_host_for_each_session(ha->host, qla4xxx_fail_session);4878 4879	if (test_bit(DPC_RESET_HA, &ha->dpc_flags))4880		reset_chip = 1;4881 4882	/* For the DPC_RESET_HA_INTR case (ISP-4xxx specific)4883	 * do not reset adapter, jump to initialize_adapter */4884	if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {4885		status = QLA_SUCCESS;4886		goto recover_ha_init_adapter;4887	}4888 4889	/* For the ISP-8xxx adapter, issue a stop_firmware if invoked4890	 * from eh_host_reset or ioctl module */4891	if (is_qla80XX(ha) && !reset_chip &&4892	    test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) {4893 4894		DEBUG2(ql4_printk(KERN_INFO, ha,4895		    "scsi%ld: %s - Performing stop_firmware...\n",4896		    ha->host_no, __func__));4897		status = ha->isp_ops->reset_firmware(ha);4898		if (status == QLA_SUCCESS) {4899			ha->isp_ops->disable_intrs(ha);4900			qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);4901			qla4xxx_abort_active_cmds(ha, DID_RESET << 16);4902		} else {4903			/* If the stop_firmware fails then4904			 * reset the entire chip */4905			reset_chip = 1;4906			clear_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags);4907			set_bit(DPC_RESET_HA, &ha->dpc_flags);4908		}4909	}4910 4911	/* Issue full chip reset if recovering from a catastrophic error,4912	 * or if stop_firmware fails for ISP-8xxx.4913	 * This is the default case for ISP-4xxx */4914	if (is_qla40XX(ha) || reset_chip) {4915		if (is_qla40XX(ha))4916			goto chip_reset;4917 4918		/* Check if 8XXX firmware is alive or not4919		 * We may have arrived here from NEED_RESET4920		 * detection only */4921		if (test_bit(AF_FW_RECOVERY, &ha->flags))4922			goto chip_reset;4923 4924		wait = jiffies + (FW_ALIVE_WAIT_TOV * HZ);4925		while (time_before(jiffies, wait)) {4926			if (qla4_8xxx_check_fw_alive(ha)) {4927				qla4xxx_mailbox_premature_completion(ha);4928				break;4929			}4930 4931			set_current_state(TASK_UNINTERRUPTIBLE);4932			schedule_timeout(HZ);4933		}4934chip_reset:4935		if (!test_bit(AF_FW_RECOVERY, &ha->flags))4936			qla4xxx_cmd_wait(ha);4937 4938		qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);4939		DEBUG2(ql4_printk(KERN_INFO, ha,4940		    "scsi%ld: %s - Performing chip reset..\n",4941		    ha->host_no, __func__));4942		status = ha->isp_ops->reset_chip(ha);4943		qla4xxx_abort_active_cmds(ha, DID_RESET << 16);4944	}4945 4946	/* Flush any pending ddb changed AENs */4947	qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);4948 4949recover_ha_init_adapter:4950	/* Upon successful firmware/chip reset, re-initialize the adapter */4951	if (status == QLA_SUCCESS) {4952		/* For ISP-4xxx, force function 1 to always initialize4953		 * before function 3 to prevent both funcions from4954		 * stepping on top of the other */4955		if (is_qla40XX(ha) && (ha->mac_index == 3))4956			ssleep(6);4957 4958		/* NOTE: AF_ONLINE flag set upon successful completion of4959		 * qla4xxx_initialize_adapter */4960		status = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);4961		if (is_qla80XX(ha) && (status == QLA_ERROR)) {4962			status = qla4_8xxx_check_init_adapter_retry(ha);4963			if (status == QLA_ERROR) {4964				ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Don't retry recover adapter\n",4965					   ha->host_no, __func__);4966				qla4xxx_dead_adapter_cleanup(ha);4967				clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);4968				clear_bit(DPC_RESET_HA, &ha->dpc_flags);4969				clear_bit(DPC_RESET_HA_FW_CONTEXT,4970					  &ha->dpc_flags);4971				goto exit_recover;4972			}4973		}4974	}4975 4976	/* Retry failed adapter initialization, if necessary4977	 * Do not retry initialize_adapter for RESET_HA_INTR (ISP-4xxx specific)4978	 * case to prevent ping-pong resets between functions */4979	if (!test_bit(AF_ONLINE, &ha->flags) &&4980	    !test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {4981		/* Adapter initialization failed, see if we can retry4982		 * resetting the ha.4983		 * Since we don't want to block the DPC for too long4984		 * with multiple resets in the same thread,4985		 * utilize DPC to retry */4986		if (is_qla80XX(ha)) {4987			ha->isp_ops->idc_lock(ha);4988			dev_state = qla4_8xxx_rd_direct(ha,4989							QLA8XXX_CRB_DEV_STATE);4990			ha->isp_ops->idc_unlock(ha);4991			if (dev_state == QLA8XXX_DEV_FAILED) {4992				ql4_printk(KERN_INFO, ha, "%s: don't retry "4993					   "recover adapter. H/W is in Failed "4994					   "state\n", __func__);4995				qla4xxx_dead_adapter_cleanup(ha);4996				clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);4997				clear_bit(DPC_RESET_HA, &ha->dpc_flags);4998				clear_bit(DPC_RESET_HA_FW_CONTEXT,4999						&ha->dpc_flags);5000				status = QLA_ERROR;5001 5002				goto exit_recover;5003			}5004		}5005 5006		if (!test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags)) {5007			ha->retry_reset_ha_cnt = MAX_RESET_HA_RETRIES;5008			DEBUG2(printk("scsi%ld: recover adapter - retrying "5009				      "(%d) more times\n", ha->host_no,5010				      ha->retry_reset_ha_cnt));5011			set_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);5012			status = QLA_ERROR;5013		} else {5014			if (ha->retry_reset_ha_cnt > 0) {5015				/* Schedule another Reset HA--DPC will retry */5016				ha->retry_reset_ha_cnt--;5017				DEBUG2(printk("scsi%ld: recover adapter - "5018					      "retry remaining %d\n",5019					      ha->host_no,5020					      ha->retry_reset_ha_cnt));5021				status = QLA_ERROR;5022			}5023 5024			if (ha->retry_reset_ha_cnt == 0) {5025				/* Recover adapter retries have been exhausted.5026				 * Adapter DEAD */5027				DEBUG2(printk("scsi%ld: recover adapter "5028					      "failed - board disabled\n",5029					      ha->host_no));5030				qla4xxx_dead_adapter_cleanup(ha);5031				clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);5032				clear_bit(DPC_RESET_HA, &ha->dpc_flags);5033				clear_bit(DPC_RESET_HA_FW_CONTEXT,5034					  &ha->dpc_flags);5035				status = QLA_ERROR;5036			}5037		}5038	} else {5039		clear_bit(DPC_RESET_HA, &ha->dpc_flags);5040		clear_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags);5041		clear_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags);5042	}5043 5044exit_recover:5045	ha->adapter_error_count++;5046 5047	if (test_bit(AF_ONLINE, &ha->flags))5048		ha->isp_ops->enable_intrs(ha);5049 5050	scsi_unblock_requests(ha->host);5051 5052	clear_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);5053	DEBUG2(printk("scsi%ld: recover adapter: %s\n", ha->host_no,5054	    status == QLA_ERROR ? "FAILED" : "SUCCEEDED"));5055 5056	return status;5057}5058 5059static void qla4xxx_relogin_devices(struct iscsi_cls_session *cls_session)5060{5061	struct iscsi_session *sess;5062	struct ddb_entry *ddb_entry;5063	struct scsi_qla_host *ha;5064 5065	sess = cls_session->dd_data;5066	ddb_entry = sess->dd_data;5067	ha = ddb_entry->ha;5068	if (!iscsi_is_session_online(cls_session)) {5069		if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) {5070			ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"5071				   " unblock session\n", ha->host_no, __func__,5072				   ddb_entry->fw_ddb_index);5073			iscsi_unblock_session(ddb_entry->sess);5074		} else {5075			/* Trigger relogin */5076			if (ddb_entry->ddb_type == FLASH_DDB) {5077				if (!(test_bit(DF_RELOGIN, &ddb_entry->flags) ||5078				      test_bit(DF_DISABLE_RELOGIN,5079					       &ddb_entry->flags)))5080					qla4xxx_arm_relogin_timer(ddb_entry);5081			} else5082				iscsi_session_failure(cls_session->dd_data,5083						      ISCSI_ERR_CONN_FAILED);5084		}5085	}5086}5087 5088int qla4xxx_unblock_flash_ddb(struct iscsi_cls_session *cls_session)5089{5090	struct iscsi_session *sess;5091	struct ddb_entry *ddb_entry;5092	struct scsi_qla_host *ha;5093 5094	sess = cls_session->dd_data;5095	ddb_entry = sess->dd_data;5096	ha = ddb_entry->ha;5097	ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"5098		   " unblock session\n", ha->host_no, __func__,5099		   ddb_entry->fw_ddb_index);5100 5101	iscsi_unblock_session(ddb_entry->sess);5102 5103	/* Start scan target */5104	if (test_bit(AF_ONLINE, &ha->flags)) {5105		ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"5106			   " start scan\n", ha->host_no, __func__,5107			   ddb_entry->fw_ddb_index);5108		queue_work(ddb_entry->sess->workq, &ddb_entry->sess->scan_work);5109	}5110	return QLA_SUCCESS;5111}5112 5113int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session)5114{5115	struct iscsi_session *sess;5116	struct ddb_entry *ddb_entry;5117	struct scsi_qla_host *ha;5118	int status = QLA_SUCCESS;5119 5120	sess = cls_session->dd_data;5121	ddb_entry = sess->dd_data;5122	ha = ddb_entry->ha;5123	ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"5124		   " unblock user space session\n", ha->host_no, __func__,5125		   ddb_entry->fw_ddb_index);5126 5127	if (!iscsi_is_session_online(cls_session)) {5128		iscsi_conn_start(ddb_entry->conn);5129		iscsi_conn_login_event(ddb_entry->conn,5130				       ISCSI_CONN_STATE_LOGGED_IN);5131	} else {5132		ql4_printk(KERN_INFO, ha,5133			   "scsi%ld: %s: ddb[%d] session [%d] already logged in\n",5134			   ha->host_no, __func__, ddb_entry->fw_ddb_index,5135			   cls_session->sid);5136		status = QLA_ERROR;5137	}5138 5139	return status;5140}5141 5142static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha)5143{5144	iscsi_host_for_each_session(ha->host, qla4xxx_relogin_devices);5145}5146 5147static void qla4xxx_relogin_flash_ddb(struct iscsi_cls_session *cls_sess)5148{5149	uint16_t relogin_timer;5150	struct iscsi_session *sess;5151	struct ddb_entry *ddb_entry;5152	struct scsi_qla_host *ha;5153 5154	sess = cls_sess->dd_data;5155	ddb_entry = sess->dd_data;5156	ha = ddb_entry->ha;5157 5158	relogin_timer = max(ddb_entry->default_relogin_timeout,5159			    (uint16_t)RELOGIN_TOV);5160	atomic_set(&ddb_entry->relogin_timer, relogin_timer);5161 5162	DEBUG2(ql4_printk(KERN_INFO, ha,5163			  "scsi%ld: Relogin index [%d]. TOV=%d\n", ha->host_no,5164			  ddb_entry->fw_ddb_index, relogin_timer));5165 5166	qla4xxx_login_flash_ddb(cls_sess);5167}5168 5169static void qla4xxx_dpc_relogin(struct iscsi_cls_session *cls_sess)5170{5171	struct iscsi_session *sess;5172	struct ddb_entry *ddb_entry;5173	struct scsi_qla_host *ha;5174 5175	sess = cls_sess->dd_data;5176	ddb_entry = sess->dd_data;5177	ha = ddb_entry->ha;5178 5179	if (!(ddb_entry->ddb_type == FLASH_DDB))5180		return;5181 5182	if (test_bit(DF_DISABLE_RELOGIN, &ddb_entry->flags))5183		return;5184 5185	if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags) &&5186	    !iscsi_is_session_online(cls_sess)) {5187		DEBUG2(ql4_printk(KERN_INFO, ha,5188				  "relogin issued\n"));5189		qla4xxx_relogin_flash_ddb(cls_sess);5190	}5191}5192 5193void qla4xxx_wake_dpc(struct scsi_qla_host *ha)5194{5195	if (ha->dpc_thread)5196		queue_work(ha->dpc_thread, &ha->dpc_work);5197}5198 5199static struct qla4_work_evt *5200qla4xxx_alloc_work(struct scsi_qla_host *ha, uint32_t data_size,5201		   enum qla4_work_type type)5202{5203	struct qla4_work_evt *e;5204	uint32_t size = sizeof(struct qla4_work_evt) + data_size;5205 5206	e = kzalloc(size, GFP_ATOMIC);5207	if (!e)5208		return NULL;5209 5210	INIT_LIST_HEAD(&e->list);5211	e->type = type;5212	return e;5213}5214 5215static void qla4xxx_post_work(struct scsi_qla_host *ha,5216			     struct qla4_work_evt *e)5217{5218	unsigned long flags;5219 5220	spin_lock_irqsave(&ha->work_lock, flags);5221	list_add_tail(&e->list, &ha->work_list);5222	spin_unlock_irqrestore(&ha->work_lock, flags);5223	qla4xxx_wake_dpc(ha);5224}5225 5226int qla4xxx_post_aen_work(struct scsi_qla_host *ha,5227			  enum iscsi_host_event_code aen_code,5228			  uint32_t data_size, uint8_t *data)5229{5230	struct qla4_work_evt *e;5231 5232	e = qla4xxx_alloc_work(ha, data_size, QLA4_EVENT_AEN);5233	if (!e)5234		return QLA_ERROR;5235 5236	e->u.aen.code = aen_code;5237	e->u.aen.data_size = data_size;5238	memcpy(e->u.aen.data, data, data_size);5239 5240	qla4xxx_post_work(ha, e);5241 5242	return QLA_SUCCESS;5243}5244 5245int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha,5246			       uint32_t status, uint32_t pid,5247			       uint32_t data_size, uint8_t *data)5248{5249	struct qla4_work_evt *e;5250 5251	e = qla4xxx_alloc_work(ha, data_size, QLA4_EVENT_PING_STATUS);5252	if (!e)5253		return QLA_ERROR;5254 5255	e->u.ping.status = status;5256	e->u.ping.pid = pid;5257	e->u.ping.data_size = data_size;5258	memcpy(e->u.ping.data, data, data_size);5259 5260	qla4xxx_post_work(ha, e);5261 5262	return QLA_SUCCESS;5263}5264 5265static void qla4xxx_do_work(struct scsi_qla_host *ha)5266{5267	struct qla4_work_evt *e, *tmp;5268	unsigned long flags;5269	LIST_HEAD(work);5270 5271	spin_lock_irqsave(&ha->work_lock, flags);5272	list_splice_init(&ha->work_list, &work);5273	spin_unlock_irqrestore(&ha->work_lock, flags);5274 5275	list_for_each_entry_safe(e, tmp, &work, list) {5276		list_del_init(&e->list);5277 5278		switch (e->type) {5279		case QLA4_EVENT_AEN:5280			iscsi_post_host_event(ha->host_no,5281					      &qla4xxx_iscsi_transport,5282					      e->u.aen.code,5283					      e->u.aen.data_size,5284					      e->u.aen.data);5285			break;5286		case QLA4_EVENT_PING_STATUS:5287			iscsi_ping_comp_event(ha->host_no,5288					      &qla4xxx_iscsi_transport,5289					      e->u.ping.status,5290					      e->u.ping.pid,5291					      e->u.ping.data_size,5292					      e->u.ping.data);5293			break;5294		default:5295			ql4_printk(KERN_WARNING, ha, "event type: 0x%x not "5296				   "supported", e->type);5297		}5298		kfree(e);5299	}5300}5301 5302/**5303 * qla4xxx_do_dpc - dpc routine5304 * @work: Context to obtain pointer to host adapter structure.5305 *5306 * This routine is a task that is schedule by the interrupt handler5307 * to perform the background processing for interrupts.  We put it5308 * on a task queue that is consumed whenever the scheduler runs; that's5309 * so you can do anything (i.e. put the process to sleep etc).  In fact,5310 * the mid-level tries to sleep when it reaches the driver threshold5311 * "host->can_queue". This can cause a panic if we were in our interrupt code.5312 **/5313static void qla4xxx_do_dpc(struct work_struct *work)5314{5315	struct scsi_qla_host *ha =5316		container_of(work, struct scsi_qla_host, dpc_work);5317	int status = QLA_ERROR;5318 5319	DEBUG2(ql4_printk(KERN_INFO, ha,5320			  "scsi%ld: %s: DPC handler waking up. flags = 0x%08lx, dpc_flags = 0x%08lx\n",5321			  ha->host_no, __func__, ha->flags, ha->dpc_flags));5322 5323	/* Initialization not yet finished. Don't do anything yet. */5324	if (!test_bit(AF_INIT_DONE, &ha->flags))5325		return;5326 5327	if (test_bit(AF_EEH_BUSY, &ha->flags)) {5328		DEBUG2(printk(KERN_INFO "scsi%ld: %s: flags = %lx\n",5329		    ha->host_no, __func__, ha->flags));5330		return;5331	}5332 5333	/* post events to application */5334	qla4xxx_do_work(ha);5335 5336	if (is_qla80XX(ha)) {5337		if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {5338			if (is_qla8032(ha) || is_qla8042(ha)) {5339				ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n",5340					   __func__);5341				/* disable pause frame for ISP83xx */5342				qla4_83xx_disable_pause(ha);5343			}5344 5345			ha->isp_ops->idc_lock(ha);5346			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,5347					    QLA8XXX_DEV_FAILED);5348			ha->isp_ops->idc_unlock(ha);5349			ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");5350			qla4_8xxx_device_state_handler(ha);5351		}5352 5353		if (test_bit(DPC_POST_IDC_ACK, &ha->dpc_flags)) {5354			if (is_qla8042(ha)) {5355				if (ha->idc_info.info2 &5356				    ENABLE_INTERNAL_LOOPBACK) {5357					ql4_printk(KERN_INFO, ha, "%s: Disabling ACB\n",5358						   __func__);5359					status = qla4_84xx_config_acb(ha,5360							    ACB_CONFIG_DISABLE);5361					if (status != QLA_SUCCESS) {5362						ql4_printk(KERN_INFO, ha, "%s: ACB config failed\n",5363							   __func__);5364					}5365				}5366			}5367			qla4_83xx_post_idc_ack(ha);5368			clear_bit(DPC_POST_IDC_ACK, &ha->dpc_flags);5369		}5370 5371		if (is_qla8042(ha) &&5372		    test_bit(DPC_RESTORE_ACB, &ha->dpc_flags)) {5373			ql4_printk(KERN_INFO, ha, "%s: Restoring ACB\n",5374				   __func__);5375			if (qla4_84xx_config_acb(ha, ACB_CONFIG_SET) !=5376			    QLA_SUCCESS) {5377				ql4_printk(KERN_INFO, ha, "%s: ACB config failed ",5378					   __func__);5379			}5380			clear_bit(DPC_RESTORE_ACB, &ha->dpc_flags);5381		}5382 5383		if (test_and_clear_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags)) {5384			qla4_8xxx_need_qsnt_handler(ha);5385		}5386	}5387 5388	if (!test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) &&5389	    (test_bit(DPC_RESET_HA, &ha->dpc_flags) ||5390	    test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) ||5391	    test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))) {5392		if ((is_qla8022(ha) && ql4xdontresethba) ||5393		    ((is_qla8032(ha) || is_qla8042(ha)) &&5394		     qla4_83xx_idc_dontreset(ha))) {5395			DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n",5396			    ha->host_no, __func__));5397			clear_bit(DPC_RESET_HA, &ha->dpc_flags);5398			clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);5399			clear_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags);5400			goto dpc_post_reset_ha;5401		}5402		if (test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags) ||5403		    test_bit(DPC_RESET_HA, &ha->dpc_flags))5404			qla4xxx_recover_adapter(ha);5405 5406		if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {5407			uint8_t wait_time = RESET_INTR_TOV;5408 5409			while ((readw(&ha->reg->ctrl_status) &5410				(CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) {5411				if (--wait_time == 0)5412					break;5413				msleep(1000);5414			}5415			if (wait_time == 0)5416				DEBUG2(printk("scsi%ld: %s: SR|FSR "5417					      "bit not cleared-- resetting\n",5418					      ha->host_no, __func__));5419			qla4xxx_abort_active_cmds(ha, DID_RESET << 16);5420			if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) {5421				qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);5422				status = qla4xxx_recover_adapter(ha);5423			}5424			clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);5425			if (status == QLA_SUCCESS)5426				ha->isp_ops->enable_intrs(ha);5427		}5428	}5429 5430dpc_post_reset_ha:5431	/* ---- process AEN? --- */5432	if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags))5433		qla4xxx_process_aen(ha, PROCESS_ALL_AENS);5434 5435	/* ---- Get DHCP IP Address? --- */5436	if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags))5437		qla4xxx_get_dhcp_ip_address(ha);5438 5439	/* ---- relogin device? --- */5440	if (adapter_up(ha) &&5441	    test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) {5442		iscsi_host_for_each_session(ha->host, qla4xxx_dpc_relogin);5443	}5444 5445	/* ---- link change? --- */5446	if (!test_bit(AF_LOOPBACK, &ha->flags) &&5447	    test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) {5448		if (!test_bit(AF_LINK_UP, &ha->flags)) {5449			/* ---- link down? --- */5450			qla4xxx_mark_all_devices_missing(ha);5451		} else {5452			/* ---- link up? --- *5453			 * F/W will auto login to all devices ONLY ONCE after5454			 * link up during driver initialization and runtime5455			 * fatal error recovery.  Therefore, the driver must5456			 * manually relogin to devices when recovering from5457			 * connection failures, logouts, expired KATO, etc. */5458			if (test_and_clear_bit(AF_BUILD_DDB_LIST, &ha->flags)) {5459				qla4xxx_build_ddb_list(ha, ha->is_reset);5460				iscsi_host_for_each_session(ha->host,5461						qla4xxx_login_flash_ddb);5462			} else5463				qla4xxx_relogin_all_devices(ha);5464		}5465	}5466	if (test_and_clear_bit(DPC_SYSFS_DDB_EXPORT, &ha->dpc_flags)) {5467		if (qla4xxx_sysfs_ddb_export(ha))5468			ql4_printk(KERN_ERR, ha, "%s: Error exporting ddb to sysfs\n",5469				   __func__);5470	}5471}5472 5473/**5474 * qla4xxx_free_adapter - release the adapter5475 * @ha: pointer to adapter structure5476 **/5477static void qla4xxx_free_adapter(struct scsi_qla_host *ha)5478{5479	qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16);5480 5481	/* Turn-off interrupts on the card. */5482	ha->isp_ops->disable_intrs(ha);5483 5484	if (is_qla40XX(ha)) {5485		writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),5486		       &ha->reg->ctrl_status);5487		readl(&ha->reg->ctrl_status);5488	} else if (is_qla8022(ha)) {5489		writel(0, &ha->qla4_82xx_reg->host_int);5490		readl(&ha->qla4_82xx_reg->host_int);5491	} else if (is_qla8032(ha) || is_qla8042(ha)) {5492		writel(0, &ha->qla4_83xx_reg->risc_intr);5493		readl(&ha->qla4_83xx_reg->risc_intr);5494	}5495 5496	/* Remove timer thread, if present */5497	if (ha->timer_active)5498		qla4xxx_stop_timer(ha);5499 5500	/* Kill the kernel thread for this host */5501	if (ha->dpc_thread)5502		destroy_workqueue(ha->dpc_thread);5503 5504	/* Kill the kernel thread for this host */5505	if (ha->task_wq)5506		destroy_workqueue(ha->task_wq);5507 5508	/* Put firmware in known state */5509	ha->isp_ops->reset_firmware(ha);5510 5511	if (is_qla80XX(ha)) {5512		ha->isp_ops->idc_lock(ha);5513		qla4_8xxx_clear_drv_active(ha);5514		ha->isp_ops->idc_unlock(ha);5515	}5516 5517	/* Detach interrupts */5518	qla4xxx_free_irqs(ha);5519 5520	/* free extra memory */5521	qla4xxx_mem_free(ha);5522}5523 5524int qla4_8xxx_iospace_config(struct scsi_qla_host *ha)5525{5526	int status = 0;5527	unsigned long mem_base, mem_len;5528	struct pci_dev *pdev = ha->pdev;5529 5530	status = pci_request_regions(pdev, DRIVER_NAME);5531	if (status) {5532		printk(KERN_WARNING5533		    "scsi(%ld) Failed to reserve PIO regions (%s) "5534		    "status=%d\n", ha->host_no, pci_name(pdev), status);5535		goto iospace_error_exit;5536	}5537 5538	DEBUG2(printk(KERN_INFO "%s: revision-id=%d\n",5539	    __func__, pdev->revision));5540	ha->revision_id = pdev->revision;5541 5542	/* remap phys address */5543	mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */5544	mem_len = pci_resource_len(pdev, 0);5545	DEBUG2(printk(KERN_INFO "%s: ioremap from %lx a size of %lx\n",5546	    __func__, mem_base, mem_len));5547 5548	/* mapping of pcibase pointer */5549	ha->nx_pcibase = (unsigned long)ioremap(mem_base, mem_len);5550	if (!ha->nx_pcibase) {5551		printk(KERN_ERR5552		    "cannot remap MMIO (%s), aborting\n", pci_name(pdev));5553		pci_release_regions(ha->pdev);5554		goto iospace_error_exit;5555	}5556 5557	/* Mapping of IO base pointer, door bell read and write pointer */5558 5559	/* mapping of IO base pointer */5560	if (is_qla8022(ha)) {5561		ha->qla4_82xx_reg = (struct device_reg_82xx  __iomem *)5562				    ((uint8_t *)ha->nx_pcibase + 0xbc000 +5563				     (ha->pdev->devfn << 11));5564		ha->nx_db_wr_ptr = (ha->pdev->devfn == 4 ? QLA82XX_CAM_RAM_DB1 :5565				    QLA82XX_CAM_RAM_DB2);5566	} else if (is_qla8032(ha) || is_qla8042(ha)) {5567		ha->qla4_83xx_reg = (struct device_reg_83xx __iomem *)5568				    ((uint8_t *)ha->nx_pcibase);5569	}5570 5571	return 0;5572iospace_error_exit:5573	return -ENOMEM;5574}5575 5576/***5577 * qla4xxx_iospace_config - maps registers5578 * @ha: pointer to adapter structure5579 *5580 * This routines maps HBA's registers from the pci address space5581 * into the kernel virtual address space for memory mapped i/o.5582 **/5583int qla4xxx_iospace_config(struct scsi_qla_host *ha)5584{5585	unsigned long pio, pio_len, pio_flags;5586	unsigned long mmio, mmio_len, mmio_flags;5587 5588	pio = pci_resource_start(ha->pdev, 0);5589	pio_len = pci_resource_len(ha->pdev, 0);5590	pio_flags = pci_resource_flags(ha->pdev, 0);5591	if (pio_flags & IORESOURCE_IO) {5592		if (pio_len < MIN_IOBASE_LEN) {5593			ql4_printk(KERN_WARNING, ha,5594				"Invalid PCI I/O region size\n");5595			pio = 0;5596		}5597	} else {5598		ql4_printk(KERN_WARNING, ha, "region #0 not a PIO resource\n");5599		pio = 0;5600	}5601 5602	/* Use MMIO operations for all accesses. */5603	mmio = pci_resource_start(ha->pdev, 1);5604	mmio_len = pci_resource_len(ha->pdev, 1);5605	mmio_flags = pci_resource_flags(ha->pdev, 1);5606 5607	if (!(mmio_flags & IORESOURCE_MEM)) {5608		ql4_printk(KERN_ERR, ha,5609		    "region #0 not an MMIO resource, aborting\n");5610 5611		goto iospace_error_exit;5612	}5613 5614	if (mmio_len < MIN_IOBASE_LEN) {5615		ql4_printk(KERN_ERR, ha,5616		    "Invalid PCI mem region size, aborting\n");5617		goto iospace_error_exit;5618	}5619 5620	if (pci_request_regions(ha->pdev, DRIVER_NAME)) {5621		ql4_printk(KERN_WARNING, ha,5622		    "Failed to reserve PIO/MMIO regions\n");5623 5624		goto iospace_error_exit;5625	}5626 5627	ha->pio_address = pio;5628	ha->pio_length = pio_len;5629	ha->reg = ioremap(mmio, MIN_IOBASE_LEN);5630	if (!ha->reg) {5631		ql4_printk(KERN_ERR, ha,5632		    "cannot remap MMIO, aborting\n");5633 5634		goto iospace_error_exit;5635	}5636 5637	return 0;5638 5639iospace_error_exit:5640	return -ENOMEM;5641}5642 5643static struct isp_operations qla4xxx_isp_ops = {5644	.iospace_config         = qla4xxx_iospace_config,5645	.pci_config             = qla4xxx_pci_config,5646	.disable_intrs          = qla4xxx_disable_intrs,5647	.enable_intrs           = qla4xxx_enable_intrs,5648	.start_firmware         = qla4xxx_start_firmware,5649	.intr_handler           = qla4xxx_intr_handler,5650	.interrupt_service_routine = qla4xxx_interrupt_service_routine,5651	.reset_chip             = qla4xxx_soft_reset,5652	.reset_firmware         = qla4xxx_hw_reset,5653	.queue_iocb             = qla4xxx_queue_iocb,5654	.complete_iocb          = qla4xxx_complete_iocb,5655	.rd_shdw_req_q_out      = qla4xxx_rd_shdw_req_q_out,5656	.rd_shdw_rsp_q_in       = qla4xxx_rd_shdw_rsp_q_in,5657	.get_sys_info           = qla4xxx_get_sys_info,5658	.queue_mailbox_command	= qla4xxx_queue_mbox_cmd,5659	.process_mailbox_interrupt = qla4xxx_process_mbox_intr,5660};5661 5662static struct isp_operations qla4_82xx_isp_ops = {5663	.iospace_config         = qla4_8xxx_iospace_config,5664	.pci_config             = qla4_8xxx_pci_config,5665	.disable_intrs          = qla4_82xx_disable_intrs,5666	.enable_intrs           = qla4_82xx_enable_intrs,5667	.start_firmware         = qla4_8xxx_load_risc,5668	.restart_firmware	= qla4_82xx_try_start_fw,5669	.intr_handler           = qla4_82xx_intr_handler,5670	.interrupt_service_routine = qla4_82xx_interrupt_service_routine,5671	.need_reset		= qla4_8xxx_need_reset,5672	.reset_chip             = qla4_82xx_isp_reset,5673	.reset_firmware         = qla4_8xxx_stop_firmware,5674	.queue_iocb             = qla4_82xx_queue_iocb,5675	.complete_iocb          = qla4_82xx_complete_iocb,5676	.rd_shdw_req_q_out      = qla4_82xx_rd_shdw_req_q_out,5677	.rd_shdw_rsp_q_in       = qla4_82xx_rd_shdw_rsp_q_in,5678	.get_sys_info           = qla4_8xxx_get_sys_info,5679	.rd_reg_direct		= qla4_82xx_rd_32,5680	.wr_reg_direct		= qla4_82xx_wr_32,5681	.rd_reg_indirect	= qla4_82xx_md_rd_32,5682	.wr_reg_indirect	= qla4_82xx_md_wr_32,5683	.idc_lock		= qla4_82xx_idc_lock,5684	.idc_unlock		= qla4_82xx_idc_unlock,5685	.rom_lock_recovery	= qla4_82xx_rom_lock_recovery,5686	.queue_mailbox_command	= qla4_82xx_queue_mbox_cmd,5687	.process_mailbox_interrupt = qla4_82xx_process_mbox_intr,5688};5689 5690static struct isp_operations qla4_83xx_isp_ops = {5691	.iospace_config		= qla4_8xxx_iospace_config,5692	.pci_config		= qla4_8xxx_pci_config,5693	.disable_intrs		= qla4_83xx_disable_intrs,5694	.enable_intrs		= qla4_83xx_enable_intrs,5695	.start_firmware		= qla4_8xxx_load_risc,5696	.restart_firmware	= qla4_83xx_start_firmware,5697	.intr_handler		= qla4_83xx_intr_handler,5698	.interrupt_service_routine = qla4_83xx_interrupt_service_routine,5699	.need_reset		= qla4_8xxx_need_reset,5700	.reset_chip		= qla4_83xx_isp_reset,5701	.reset_firmware		= qla4_8xxx_stop_firmware,5702	.queue_iocb		= qla4_83xx_queue_iocb,5703	.complete_iocb		= qla4_83xx_complete_iocb,5704	.rd_shdw_req_q_out	= qla4xxx_rd_shdw_req_q_out,5705	.rd_shdw_rsp_q_in	= qla4xxx_rd_shdw_rsp_q_in,5706	.get_sys_info		= qla4_8xxx_get_sys_info,5707	.rd_reg_direct		= qla4_83xx_rd_reg,5708	.wr_reg_direct		= qla4_83xx_wr_reg,5709	.rd_reg_indirect	= qla4_83xx_rd_reg_indirect,5710	.wr_reg_indirect	= qla4_83xx_wr_reg_indirect,5711	.idc_lock		= qla4_83xx_drv_lock,5712	.idc_unlock		= qla4_83xx_drv_unlock,5713	.rom_lock_recovery	= qla4_83xx_rom_lock_recovery,5714	.queue_mailbox_command	= qla4_83xx_queue_mbox_cmd,5715	.process_mailbox_interrupt = qla4_83xx_process_mbox_intr,5716};5717 5718uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha)5719{5720	return (uint16_t)le32_to_cpu(ha->shadow_regs->req_q_out);5721}5722 5723uint16_t qla4_82xx_rd_shdw_req_q_out(struct scsi_qla_host *ha)5724{5725	return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->req_q_out));5726}5727 5728uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)5729{5730	return (uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in);5731}5732 5733uint16_t qla4_82xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)5734{5735	return (uint16_t)le32_to_cpu(readl(&ha->qla4_82xx_reg->rsp_q_in));5736}5737 5738static ssize_t qla4xxx_show_boot_eth_info(void *data, int type, char *buf)5739{5740	struct scsi_qla_host *ha = data;5741	char *str = buf;5742	int rc;5743 5744	switch (type) {5745	case ISCSI_BOOT_ETH_FLAGS:5746		rc = sprintf(str, "%d\n", (char)SYSFS_FLAG_FW_SEL_BOOT);5747		break;5748	case ISCSI_BOOT_ETH_INDEX:5749		rc = sprintf(str, "0\n");5750		break;5751	case ISCSI_BOOT_ETH_MAC:5752		rc = sysfs_format_mac(str, ha->my_mac,5753				      MAC_ADDR_LEN);5754		break;5755	default:5756		rc = -ENOSYS;5757		break;5758	}5759	return rc;5760}5761 5762static umode_t qla4xxx_eth_get_attr_visibility(void *data, int type)5763{5764	int rc;5765 5766	switch (type) {5767	case ISCSI_BOOT_ETH_FLAGS:5768	case ISCSI_BOOT_ETH_MAC:5769	case ISCSI_BOOT_ETH_INDEX:5770		rc = S_IRUGO;5771		break;5772	default:5773		rc = 0;5774		break;5775	}5776	return rc;5777}5778 5779static ssize_t qla4xxx_show_boot_ini_info(void *data, int type, char *buf)5780{5781	struct scsi_qla_host *ha = data;5782	char *str = buf;5783	int rc;5784 5785	switch (type) {5786	case ISCSI_BOOT_INI_INITIATOR_NAME:5787		rc = sprintf(str, "%s\n", ha->name_string);5788		break;5789	default:5790		rc = -ENOSYS;5791		break;5792	}5793	return rc;5794}5795 5796static umode_t qla4xxx_ini_get_attr_visibility(void *data, int type)5797{5798	int rc;5799 5800	switch (type) {5801	case ISCSI_BOOT_INI_INITIATOR_NAME:5802		rc = S_IRUGO;5803		break;5804	default:5805		rc = 0;5806		break;5807	}5808	return rc;5809}5810 5811static ssize_t5812qla4xxx_show_boot_tgt_info(struct ql4_boot_session_info *boot_sess, int type,5813			   char *buf)5814{5815	struct ql4_conn_info *boot_conn = &boot_sess->conn_list[0];5816	char *str = buf;5817	int rc;5818 5819	switch (type) {5820	case ISCSI_BOOT_TGT_NAME:5821		rc = sprintf(buf, "%s\n", (char *)&boot_sess->target_name);5822		break;5823	case ISCSI_BOOT_TGT_IP_ADDR:5824		if (boot_sess->conn_list[0].dest_ipaddr.ip_type == 0x1)5825			rc = sprintf(buf, "%pI4\n",5826				     &boot_conn->dest_ipaddr.ip_address);5827		else5828			rc = sprintf(str, "%pI6\n",5829				     &boot_conn->dest_ipaddr.ip_address);5830		break;5831	case ISCSI_BOOT_TGT_PORT:5832			rc = sprintf(str, "%d\n", boot_conn->dest_port);5833		break;5834	case ISCSI_BOOT_TGT_CHAP_NAME:5835		rc = sprintf(str,  "%.*s\n",5836			     boot_conn->chap.target_chap_name_length,5837			     (char *)&boot_conn->chap.target_chap_name);5838		break;5839	case ISCSI_BOOT_TGT_CHAP_SECRET:5840		rc = sprintf(str,  "%.*s\n",5841			     boot_conn->chap.target_secret_length,5842			     (char *)&boot_conn->chap.target_secret);5843		break;5844	case ISCSI_BOOT_TGT_REV_CHAP_NAME:5845		rc = sprintf(str,  "%.*s\n",5846			     boot_conn->chap.intr_chap_name_length,5847			     (char *)&boot_conn->chap.intr_chap_name);5848		break;5849	case ISCSI_BOOT_TGT_REV_CHAP_SECRET:5850		rc = sprintf(str,  "%.*s\n",5851			     boot_conn->chap.intr_secret_length,5852			     (char *)&boot_conn->chap.intr_secret);5853		break;5854	case ISCSI_BOOT_TGT_FLAGS:5855		rc = sprintf(str, "%d\n", (char)SYSFS_FLAG_FW_SEL_BOOT);5856		break;5857	case ISCSI_BOOT_TGT_NIC_ASSOC:5858		rc = sprintf(str, "0\n");5859		break;5860	default:5861		rc = -ENOSYS;5862		break;5863	}5864	return rc;5865}5866 5867static ssize_t qla4xxx_show_boot_tgt_pri_info(void *data, int type, char *buf)5868{5869	struct scsi_qla_host *ha = data;5870	struct ql4_boot_session_info *boot_sess = &(ha->boot_tgt.boot_pri_sess);5871 5872	return qla4xxx_show_boot_tgt_info(boot_sess, type, buf);5873}5874 5875static ssize_t qla4xxx_show_boot_tgt_sec_info(void *data, int type, char *buf)5876{5877	struct scsi_qla_host *ha = data;5878	struct ql4_boot_session_info *boot_sess = &(ha->boot_tgt.boot_sec_sess);5879 5880	return qla4xxx_show_boot_tgt_info(boot_sess, type, buf);5881}5882 5883static umode_t qla4xxx_tgt_get_attr_visibility(void *data, int type)5884{5885	int rc;5886 5887	switch (type) {5888	case ISCSI_BOOT_TGT_NAME:5889	case ISCSI_BOOT_TGT_IP_ADDR:5890	case ISCSI_BOOT_TGT_PORT:5891	case ISCSI_BOOT_TGT_CHAP_NAME:5892	case ISCSI_BOOT_TGT_CHAP_SECRET:5893	case ISCSI_BOOT_TGT_REV_CHAP_NAME:5894	case ISCSI_BOOT_TGT_REV_CHAP_SECRET:5895	case ISCSI_BOOT_TGT_NIC_ASSOC:5896	case ISCSI_BOOT_TGT_FLAGS:5897		rc = S_IRUGO;5898		break;5899	default:5900		rc = 0;5901		break;5902	}5903	return rc;5904}5905 5906static void qla4xxx_boot_release(void *data)5907{5908	struct scsi_qla_host *ha = data;5909 5910	scsi_host_put(ha->host);5911}5912 5913static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[])5914{5915	dma_addr_t buf_dma;5916	uint32_t addr, pri_addr, sec_addr;5917	uint32_t offset;5918	uint16_t func_num;5919	uint8_t val;5920	uint8_t *buf = NULL;5921	size_t size = 13 * sizeof(uint8_t);5922	int ret = QLA_SUCCESS;5923 5924	func_num = PCI_FUNC(ha->pdev->devfn);5925 5926	ql4_printk(KERN_INFO, ha, "%s: Get FW boot info for 0x%x func %d\n",5927		   __func__, ha->pdev->device, func_num);5928 5929	if (is_qla40XX(ha)) {5930		if (func_num == 1) {5931			addr = NVRAM_PORT0_BOOT_MODE;5932			pri_addr = NVRAM_PORT0_BOOT_PRI_TGT;5933			sec_addr = NVRAM_PORT0_BOOT_SEC_TGT;5934		} else if (func_num == 3) {5935			addr = NVRAM_PORT1_BOOT_MODE;5936			pri_addr = NVRAM_PORT1_BOOT_PRI_TGT;5937			sec_addr = NVRAM_PORT1_BOOT_SEC_TGT;5938		} else {5939			ret = QLA_ERROR;5940			goto exit_boot_info;5941		}5942 5943		/* Check Boot Mode */5944		val = rd_nvram_byte(ha, addr);5945		if (!(val & 0x07)) {5946			DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Adapter boot "5947					  "options : 0x%x\n", __func__, val));5948			ret = QLA_ERROR;5949			goto exit_boot_info;5950		}5951 5952		/* get primary valid target index */5953		val = rd_nvram_byte(ha, pri_addr);5954		if (val & BIT_7)5955			ddb_index[0] = (val & 0x7f);5956 5957		/* get secondary valid target index */5958		val = rd_nvram_byte(ha, sec_addr);5959		if (val & BIT_7)5960			ddb_index[1] = (val & 0x7f);5961		goto exit_boot_info;5962	} else if (is_qla80XX(ha)) {5963		buf = dma_alloc_coherent(&ha->pdev->dev, size,5964					 &buf_dma, GFP_KERNEL);5965		if (!buf) {5966			DEBUG2(ql4_printk(KERN_ERR, ha,5967					  "%s: Unable to allocate dma buffer\n",5968					   __func__));5969			ret = QLA_ERROR;5970			goto exit_boot_info;5971		}5972 5973		if (ha->port_num == 0)5974			offset = BOOT_PARAM_OFFSET_PORT0;5975		else if (ha->port_num == 1)5976			offset = BOOT_PARAM_OFFSET_PORT1;5977		else {5978			ret = QLA_ERROR;5979			goto exit_boot_info_free;5980		}5981		addr = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_iscsi_param * 4) +5982		       offset;5983		if (qla4xxx_get_flash(ha, buf_dma, addr,5984				      13 * sizeof(uint8_t)) != QLA_SUCCESS) {5985			DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash"5986					  " failed\n", ha->host_no, __func__));5987			ret = QLA_ERROR;5988			goto exit_boot_info_free;5989		}5990		/* Check Boot Mode */5991		if (!(buf[1] & 0x07)) {5992			DEBUG2(ql4_printk(KERN_INFO, ha, "Firmware boot options"5993					  " : 0x%x\n", buf[1]));5994			ret = QLA_ERROR;5995			goto exit_boot_info_free;5996		}5997 5998		/* get primary valid target index */5999		if (buf[2] & BIT_7)6000			ddb_index[0] = buf[2] & 0x7f;6001 6002		/* get secondary valid target index */6003		if (buf[11] & BIT_7)6004			ddb_index[1] = buf[11] & 0x7f;6005	} else {6006		ret = QLA_ERROR;6007		goto exit_boot_info;6008	}6009 6010	DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Primary target ID %d, Secondary"6011			  " target ID %d\n", __func__, ddb_index[0],6012			  ddb_index[1]));6013 6014exit_boot_info_free:6015	dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma);6016exit_boot_info:6017	ha->pri_ddb_idx = ddb_index[0];6018	ha->sec_ddb_idx = ddb_index[1];6019	return ret;6020}6021 6022/**6023 * qla4xxx_get_bidi_chap - Get a BIDI CHAP user and password6024 * @ha: pointer to adapter structure6025 * @username: CHAP username to be returned6026 * @password: CHAP password to be returned6027 *6028 * If a boot entry has BIDI CHAP enabled then we need to set the BIDI CHAP6029 * user and password in the sysfs entry in /sys/firmware/iscsi_boot#/.6030 * So from the CHAP cache find the first BIDI CHAP entry and set it6031 * to the boot record in sysfs.6032 **/6033static int qla4xxx_get_bidi_chap(struct scsi_qla_host *ha, char *username,6034			    char *password)6035{6036	int i, ret = -EINVAL;6037	int max_chap_entries = 0;6038	struct ql4_chap_table *chap_table;6039 6040	if (is_qla80XX(ha))6041		max_chap_entries = (ha->hw.flt_chap_size / 2) /6042						sizeof(struct ql4_chap_table);6043	else6044		max_chap_entries = MAX_CHAP_ENTRIES_40XX;6045 6046	if (!ha->chap_list) {6047		ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");6048		return ret;6049	}6050 6051	mutex_lock(&ha->chap_sem);6052	for (i = 0; i < max_chap_entries; i++) {6053		chap_table = (struct ql4_chap_table *)ha->chap_list + i;6054		if (chap_table->cookie !=6055		    cpu_to_le16(CHAP_VALID_COOKIE)) {6056			continue;6057		}6058 6059		if (chap_table->flags & BIT_7) /* local */6060			continue;6061 6062		if (!(chap_table->flags & BIT_6)) /* Not BIDI */6063			continue;6064 6065		strscpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN);6066		strscpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN);6067		ret = 0;6068		break;6069	}6070	mutex_unlock(&ha->chap_sem);6071 6072	return ret;6073}6074 6075 6076static int qla4xxx_get_boot_target(struct scsi_qla_host *ha,6077				   struct ql4_boot_session_info *boot_sess,6078				   uint16_t ddb_index)6079{6080	struct ql4_conn_info *boot_conn = &boot_sess->conn_list[0];6081	struct dev_db_entry *fw_ddb_entry;6082	dma_addr_t fw_ddb_entry_dma;6083	uint16_t idx;6084	uint16_t options;6085	int ret = QLA_SUCCESS;6086 6087	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),6088					  &fw_ddb_entry_dma, GFP_KERNEL);6089	if (!fw_ddb_entry) {6090		DEBUG2(ql4_printk(KERN_ERR, ha,6091				  "%s: Unable to allocate dma buffer.\n",6092				  __func__));6093		ret = QLA_ERROR;6094		return ret;6095	}6096 6097	if (qla4xxx_bootdb_by_index(ha, fw_ddb_entry,6098				   fw_ddb_entry_dma, ddb_index)) {6099		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: No Flash DDB found at "6100				  "index [%d]\n", __func__, ddb_index));6101		ret = QLA_ERROR;6102		goto exit_boot_target;6103	}6104 6105	/* Update target name and IP from DDB */6106	memcpy(boot_sess->target_name, fw_ddb_entry->iscsi_name,6107	       min(sizeof(boot_sess->target_name),6108		   sizeof(fw_ddb_entry->iscsi_name)));6109 6110	options = le16_to_cpu(fw_ddb_entry->options);6111	if (options & DDB_OPT_IPV6_DEVICE) {6112		memcpy(&boot_conn->dest_ipaddr.ip_address,6113		       &fw_ddb_entry->ip_addr[0], IPv6_ADDR_LEN);6114	} else {6115		boot_conn->dest_ipaddr.ip_type = 0x1;6116		memcpy(&boot_conn->dest_ipaddr.ip_address,6117		       &fw_ddb_entry->ip_addr[0], IP_ADDR_LEN);6118	}6119 6120	boot_conn->dest_port = le16_to_cpu(fw_ddb_entry->port);6121 6122	/* update chap information */6123	idx = __le16_to_cpu(fw_ddb_entry->chap_tbl_idx);6124 6125	if (BIT_7 & le16_to_cpu(fw_ddb_entry->iscsi_options))	{6126 6127		DEBUG2(ql4_printk(KERN_INFO, ha, "Setting chap\n"));6128 6129		ret = qla4xxx_get_chap(ha, (char *)&boot_conn->chap.6130				       target_chap_name,6131				       (char *)&boot_conn->chap.target_secret,6132				       idx);6133		if (ret) {6134			ql4_printk(KERN_ERR, ha, "Failed to set chap\n");6135			ret = QLA_ERROR;6136			goto exit_boot_target;6137		}6138 6139		boot_conn->chap.target_chap_name_length = QL4_CHAP_MAX_NAME_LEN;6140		boot_conn->chap.target_secret_length = QL4_CHAP_MAX_SECRET_LEN;6141	}6142 6143	if (BIT_4 & le16_to_cpu(fw_ddb_entry->iscsi_options)) {6144 6145		DEBUG2(ql4_printk(KERN_INFO, ha, "Setting BIDI chap\n"));6146 6147		ret = qla4xxx_get_bidi_chap(ha,6148				    (char *)&boot_conn->chap.intr_chap_name,6149				    (char *)&boot_conn->chap.intr_secret);6150 6151		if (ret) {6152			ql4_printk(KERN_ERR, ha, "Failed to set BIDI chap\n");6153			ret = QLA_ERROR;6154			goto exit_boot_target;6155		}6156 6157		boot_conn->chap.intr_chap_name_length = QL4_CHAP_MAX_NAME_LEN;6158		boot_conn->chap.intr_secret_length = QL4_CHAP_MAX_SECRET_LEN;6159	}6160 6161exit_boot_target:6162	dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),6163			  fw_ddb_entry, fw_ddb_entry_dma);6164	return ret;6165}6166 6167static int qla4xxx_get_boot_info(struct scsi_qla_host *ha)6168{6169	uint16_t ddb_index[2];6170	int ret = QLA_ERROR;6171	int rval;6172 6173	memset(ddb_index, 0, sizeof(ddb_index));6174	ddb_index[0] = 0xffff;6175	ddb_index[1] = 0xffff;6176	ret = get_fw_boot_info(ha, ddb_index);6177	if (ret != QLA_SUCCESS) {6178		DEBUG2(ql4_printk(KERN_INFO, ha,6179				"%s: No boot target configured.\n", __func__));6180		return ret;6181	}6182 6183	if (ql4xdisablesysfsboot)6184		return QLA_SUCCESS;6185 6186	if (ddb_index[0] == 0xffff)6187		goto sec_target;6188 6189	rval = qla4xxx_get_boot_target(ha, &(ha->boot_tgt.boot_pri_sess),6190				      ddb_index[0]);6191	if (rval != QLA_SUCCESS) {6192		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Primary boot target not "6193				  "configured\n", __func__));6194	} else6195		ret = QLA_SUCCESS;6196 6197sec_target:6198	if (ddb_index[1] == 0xffff)6199		goto exit_get_boot_info;6200 6201	rval = qla4xxx_get_boot_target(ha, &(ha->boot_tgt.boot_sec_sess),6202				      ddb_index[1]);6203	if (rval != QLA_SUCCESS) {6204		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Secondary boot target not"6205				  " configured\n", __func__));6206	} else6207		ret = QLA_SUCCESS;6208 6209exit_get_boot_info:6210	return ret;6211}6212 6213static int qla4xxx_setup_boot_info(struct scsi_qla_host *ha)6214{6215	struct iscsi_boot_kobj *boot_kobj;6216 6217	if (qla4xxx_get_boot_info(ha) != QLA_SUCCESS)6218		return QLA_ERROR;6219 6220	if (ql4xdisablesysfsboot) {6221		ql4_printk(KERN_INFO, ha,6222			   "%s: syfsboot disabled - driver will trigger login "6223			   "and publish session for discovery .\n", __func__);6224		return QLA_SUCCESS;6225	}6226 6227 6228	ha->boot_kset = iscsi_boot_create_host_kset(ha->host->host_no);6229	if (!ha->boot_kset)6230		goto kset_free;6231 6232	if (!scsi_host_get(ha->host))6233		goto kset_free;6234	boot_kobj = iscsi_boot_create_target(ha->boot_kset, 0, ha,6235					     qla4xxx_show_boot_tgt_pri_info,6236					     qla4xxx_tgt_get_attr_visibility,6237					     qla4xxx_boot_release);6238	if (!boot_kobj)6239		goto put_host;6240 6241	if (!scsi_host_get(ha->host))6242		goto kset_free;6243	boot_kobj = iscsi_boot_create_target(ha->boot_kset, 1, ha,6244					     qla4xxx_show_boot_tgt_sec_info,6245					     qla4xxx_tgt_get_attr_visibility,6246					     qla4xxx_boot_release);6247	if (!boot_kobj)6248		goto put_host;6249 6250	if (!scsi_host_get(ha->host))6251		goto kset_free;6252	boot_kobj = iscsi_boot_create_initiator(ha->boot_kset, 0, ha,6253					       qla4xxx_show_boot_ini_info,6254					       qla4xxx_ini_get_attr_visibility,6255					       qla4xxx_boot_release);6256	if (!boot_kobj)6257		goto put_host;6258 6259	if (!scsi_host_get(ha->host))6260		goto kset_free;6261	boot_kobj = iscsi_boot_create_ethernet(ha->boot_kset, 0, ha,6262					       qla4xxx_show_boot_eth_info,6263					       qla4xxx_eth_get_attr_visibility,6264					       qla4xxx_boot_release);6265	if (!boot_kobj)6266		goto put_host;6267 6268	return QLA_SUCCESS;6269 6270put_host:6271	scsi_host_put(ha->host);6272kset_free:6273	iscsi_boot_destroy_kset(ha->boot_kset);6274	return -ENOMEM;6275}6276 6277 6278static void qla4xxx_get_param_ddb(struct ddb_entry *ddb_entry,6279				  struct ql4_tuple_ddb *tddb)6280{6281	struct iscsi_cls_session *cls_sess;6282	struct iscsi_cls_conn *cls_conn;6283	struct iscsi_session *sess;6284	struct iscsi_conn *conn;6285 6286	DEBUG2(printk(KERN_INFO "Func: %s\n", __func__));6287	cls_sess = ddb_entry->sess;6288	sess = cls_sess->dd_data;6289	cls_conn = ddb_entry->conn;6290	conn = cls_conn->dd_data;6291 6292	tddb->tpgt = sess->tpgt;6293	tddb->port = conn->persistent_port;6294	strscpy(tddb->iscsi_name, sess->targetname, sizeof(tddb->iscsi_name));6295	strscpy(tddb->ip_addr, conn->persistent_address, sizeof(tddb->ip_addr));6296}6297 6298static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry,6299				      struct ql4_tuple_ddb *tddb,6300				      uint8_t *flash_isid)6301{6302	uint16_t options = 0;6303 6304	tddb->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);6305	memcpy(&tddb->iscsi_name[0], &fw_ddb_entry->iscsi_name[0],6306	       min(sizeof(tddb->iscsi_name), sizeof(fw_ddb_entry->iscsi_name)));6307 6308	options = le16_to_cpu(fw_ddb_entry->options);6309	if (options & DDB_OPT_IPV6_DEVICE)6310		sprintf(tddb->ip_addr, "%pI6", fw_ddb_entry->ip_addr);6311	else6312		sprintf(tddb->ip_addr, "%pI4", fw_ddb_entry->ip_addr);6313 6314	tddb->port = le16_to_cpu(fw_ddb_entry->port);6315 6316	if (flash_isid == NULL)6317		memcpy(&tddb->isid[0], &fw_ddb_entry->isid[0],6318		       sizeof(tddb->isid));6319	else6320		memcpy(&tddb->isid[0], &flash_isid[0], sizeof(tddb->isid));6321}6322 6323static int qla4xxx_compare_tuple_ddb(struct scsi_qla_host *ha,6324				     struct ql4_tuple_ddb *old_tddb,6325				     struct ql4_tuple_ddb *new_tddb,6326				     uint8_t is_isid_compare)6327{6328	if (strcmp(old_tddb->iscsi_name, new_tddb->iscsi_name))6329		return QLA_ERROR;6330 6331	if (strcmp(old_tddb->ip_addr, new_tddb->ip_addr))6332		return QLA_ERROR;6333 6334	if (old_tddb->port != new_tddb->port)6335		return QLA_ERROR;6336 6337	/* For multi sessions, driver generates the ISID, so do not compare6338	 * ISID in reset path since it would be a comparison between the6339	 * driver generated ISID and firmware generated ISID. This could6340	 * lead to adding duplicated DDBs in the list as driver generated6341	 * ISID would not match firmware generated ISID.6342	 */6343	if (is_isid_compare) {6344		DEBUG2(ql4_printk(KERN_INFO, ha,6345			"%s: old ISID [%pmR] New ISID [%pmR]\n",6346			__func__, old_tddb->isid, new_tddb->isid));6347 6348		if (memcmp(&old_tddb->isid[0], &new_tddb->isid[0],6349			   sizeof(old_tddb->isid)))6350			return QLA_ERROR;6351	}6352 6353	DEBUG2(ql4_printk(KERN_INFO, ha,6354			  "Match Found, fw[%d,%d,%s,%s], [%d,%d,%s,%s]",6355			  old_tddb->port, old_tddb->tpgt, old_tddb->ip_addr,6356			  old_tddb->iscsi_name, new_tddb->port, new_tddb->tpgt,6357			  new_tddb->ip_addr, new_tddb->iscsi_name));6358 6359	return QLA_SUCCESS;6360}6361 6362static int qla4xxx_is_session_exists(struct scsi_qla_host *ha,6363				     struct dev_db_entry *fw_ddb_entry,6364				     uint32_t *index)6365{6366	struct ddb_entry *ddb_entry;6367	struct ql4_tuple_ddb *fw_tddb = NULL;6368	struct ql4_tuple_ddb *tmp_tddb = NULL;6369	int idx;6370	int ret = QLA_ERROR;6371 6372	fw_tddb = vzalloc(sizeof(*fw_tddb));6373	if (!fw_tddb) {6374		DEBUG2(ql4_printk(KERN_WARNING, ha,6375				  "Memory Allocation failed.\n"));6376		ret = QLA_SUCCESS;6377		goto exit_check;6378	}6379 6380	tmp_tddb = vzalloc(sizeof(*tmp_tddb));6381	if (!tmp_tddb) {6382		DEBUG2(ql4_printk(KERN_WARNING, ha,6383				  "Memory Allocation failed.\n"));6384		ret = QLA_SUCCESS;6385		goto exit_check;6386	}6387 6388	qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb, NULL);6389 6390	for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) {6391		ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);6392		if (ddb_entry == NULL)6393			continue;6394 6395		qla4xxx_get_param_ddb(ddb_entry, tmp_tddb);6396		if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb, false)) {6397			ret = QLA_SUCCESS; /* found */6398			if (index != NULL)6399				*index = idx;6400			goto exit_check;6401		}6402	}6403 6404exit_check:6405	vfree(fw_tddb);6406	vfree(tmp_tddb);6407	return ret;6408}6409 6410/**6411 * qla4xxx_check_existing_isid - check if target with same isid exist6412 *				 in target list6413 * @list_nt: list of target6414 * @isid: isid to check6415 *6416 * This routine return QLA_SUCCESS if target with same isid exist6417 **/6418static int qla4xxx_check_existing_isid(struct list_head *list_nt, uint8_t *isid)6419{6420	struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp;6421	struct dev_db_entry *fw_ddb_entry;6422 6423	list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) {6424		fw_ddb_entry = &nt_ddb_idx->fw_ddb;6425 6426		if (memcmp(&fw_ddb_entry->isid[0], &isid[0],6427			   sizeof(nt_ddb_idx->fw_ddb.isid)) == 0) {6428			return QLA_SUCCESS;6429		}6430	}6431	return QLA_ERROR;6432}6433 6434/**6435 * qla4xxx_update_isid - compare ddbs and updated isid6436 * @ha: Pointer to host adapter structure.6437 * @list_nt: list of nt target6438 * @fw_ddb_entry: firmware ddb entry6439 *6440 * This routine update isid if ddbs have same iqn, same isid and6441 * different IP addr.6442 * Return QLA_SUCCESS if isid is updated.6443 **/6444static int qla4xxx_update_isid(struct scsi_qla_host *ha,6445			       struct list_head *list_nt,6446			       struct dev_db_entry *fw_ddb_entry)6447{6448	uint8_t base_value, i;6449 6450	base_value = fw_ddb_entry->isid[1] & 0x1f;6451	for (i = 0; i < 8; i++) {6452		fw_ddb_entry->isid[1] = (base_value | (i << 5));6453		if (qla4xxx_check_existing_isid(list_nt, fw_ddb_entry->isid))6454			break;6455	}6456 6457	if (!qla4xxx_check_existing_isid(list_nt, fw_ddb_entry->isid))6458		return QLA_ERROR;6459 6460	return QLA_SUCCESS;6461}6462 6463/**6464 * qla4xxx_should_update_isid - check if isid need to update6465 * @ha: Pointer to host adapter structure.6466 * @old_tddb: ddb tuple6467 * @new_tddb: ddb tuple6468 *6469 * Return QLA_SUCCESS if different IP, different PORT, same iqn,6470 * same isid6471 **/6472static int qla4xxx_should_update_isid(struct scsi_qla_host *ha,6473				      struct ql4_tuple_ddb *old_tddb,6474				      struct ql4_tuple_ddb *new_tddb)6475{6476	if (strcmp(old_tddb->ip_addr, new_tddb->ip_addr) == 0) {6477		/* Same ip */6478		if (old_tddb->port == new_tddb->port)6479			return QLA_ERROR;6480	}6481 6482	if (strcmp(old_tddb->iscsi_name, new_tddb->iscsi_name))6483		/* different iqn */6484		return QLA_ERROR;6485 6486	if (memcmp(&old_tddb->isid[0], &new_tddb->isid[0],6487		   sizeof(old_tddb->isid)))6488		/* different isid */6489		return QLA_ERROR;6490 6491	return QLA_SUCCESS;6492}6493 6494/**6495 * qla4xxx_is_flash_ddb_exists - check if fw_ddb_entry already exists in list_nt6496 * @ha: Pointer to host adapter structure.6497 * @list_nt: list of nt target.6498 * @fw_ddb_entry: firmware ddb entry.6499 *6500 * This routine check if fw_ddb_entry already exists in list_nt to avoid6501 * duplicate ddb in list_nt.6502 * Return QLA_SUCCESS if duplicate ddb exit in list_nl.6503 * Note: This function also update isid of DDB if required.6504 **/6505 6506static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha,6507				       struct list_head *list_nt,6508				       struct dev_db_entry *fw_ddb_entry)6509{6510	struct qla_ddb_index  *nt_ddb_idx, *nt_ddb_idx_tmp;6511	struct ql4_tuple_ddb *fw_tddb = NULL;6512	struct ql4_tuple_ddb *tmp_tddb = NULL;6513	int rval, ret = QLA_ERROR;6514 6515	fw_tddb = vzalloc(sizeof(*fw_tddb));6516	if (!fw_tddb) {6517		DEBUG2(ql4_printk(KERN_WARNING, ha,6518				  "Memory Allocation failed.\n"));6519		ret = QLA_SUCCESS;6520		goto exit_check;6521	}6522 6523	tmp_tddb = vzalloc(sizeof(*tmp_tddb));6524	if (!tmp_tddb) {6525		DEBUG2(ql4_printk(KERN_WARNING, ha,6526				  "Memory Allocation failed.\n"));6527		ret = QLA_SUCCESS;6528		goto exit_check;6529	}6530 6531	qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb, NULL);6532 6533	list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) {6534		qla4xxx_convert_param_ddb(&nt_ddb_idx->fw_ddb, tmp_tddb,6535					  nt_ddb_idx->flash_isid);6536		ret = qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb, true);6537		/* found duplicate ddb */6538		if (ret == QLA_SUCCESS)6539			goto exit_check;6540	}6541 6542	list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) {6543		qla4xxx_convert_param_ddb(&nt_ddb_idx->fw_ddb, tmp_tddb, NULL);6544 6545		ret = qla4xxx_should_update_isid(ha, tmp_tddb, fw_tddb);6546		if (ret == QLA_SUCCESS) {6547			rval = qla4xxx_update_isid(ha, list_nt, fw_ddb_entry);6548			if (rval == QLA_SUCCESS)6549				ret = QLA_ERROR;6550			else6551				ret = QLA_SUCCESS;6552 6553			goto exit_check;6554		}6555	}6556 6557exit_check:6558	vfree(fw_tddb);6559	vfree(tmp_tddb);6560	return ret;6561}6562 6563static void qla4xxx_free_ddb_list(struct list_head *list_ddb)6564{6565	struct qla_ddb_index  *ddb_idx, *ddb_idx_tmp;6566 6567	list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, list_ddb, list) {6568		list_del_init(&ddb_idx->list);6569		vfree(ddb_idx);6570	}6571}6572 6573static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha,6574					struct dev_db_entry *fw_ddb_entry)6575{6576	struct iscsi_endpoint *ep;6577	struct sockaddr_in *addr;6578	struct sockaddr_in6 *addr6;6579	struct sockaddr *t_addr;6580	struct sockaddr_storage *dst_addr;6581	char *ip;6582 6583	/* TODO: need to destroy on unload iscsi_endpoint*/6584	dst_addr = vmalloc(sizeof(*dst_addr));6585	if (!dst_addr)6586		return NULL;6587 6588	if (fw_ddb_entry->options & DDB_OPT_IPV6_DEVICE) {6589		t_addr = (struct sockaddr *)dst_addr;6590		t_addr->sa_family = AF_INET6;6591		addr6 = (struct sockaddr_in6 *)dst_addr;6592		ip = (char *)&addr6->sin6_addr;6593		memcpy(ip, fw_ddb_entry->ip_addr, IPv6_ADDR_LEN);6594		addr6->sin6_port = htons(le16_to_cpu(fw_ddb_entry->port));6595 6596	} else {6597		t_addr = (struct sockaddr *)dst_addr;6598		t_addr->sa_family = AF_INET;6599		addr = (struct sockaddr_in *)dst_addr;6600		ip = (char *)&addr->sin_addr;6601		memcpy(ip, fw_ddb_entry->ip_addr, IP_ADDR_LEN);6602		addr->sin_port = htons(le16_to_cpu(fw_ddb_entry->port));6603	}6604 6605	ep = qla4xxx_ep_connect(ha->host, (struct sockaddr *)dst_addr, 0);6606	vfree(dst_addr);6607	return ep;6608}6609 6610static int qla4xxx_verify_boot_idx(struct scsi_qla_host *ha, uint16_t idx)6611{6612	if (ql4xdisablesysfsboot)6613		return QLA_SUCCESS;6614	if (idx == ha->pri_ddb_idx || idx == ha->sec_ddb_idx)6615		return QLA_ERROR;6616	return QLA_SUCCESS;6617}6618 6619static void qla4xxx_setup_flash_ddb_entry(struct scsi_qla_host *ha,6620					  struct ddb_entry *ddb_entry,6621					  uint16_t idx)6622{6623	uint16_t def_timeout;6624 6625	ddb_entry->ddb_type = FLASH_DDB;6626	ddb_entry->fw_ddb_index = INVALID_ENTRY;6627	ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE;6628	ddb_entry->ha = ha;6629	ddb_entry->unblock_sess = qla4xxx_unblock_flash_ddb;6630	ddb_entry->ddb_change = qla4xxx_flash_ddb_change;6631	ddb_entry->chap_tbl_idx = INVALID_ENTRY;6632 6633	atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY);6634	atomic_set(&ddb_entry->relogin_timer, 0);6635	atomic_set(&ddb_entry->relogin_retry_count, 0);6636	def_timeout = le16_to_cpu(ddb_entry->fw_ddb_entry.def_timeout);6637	ddb_entry->default_relogin_timeout =6638		(def_timeout > LOGIN_TOV) && (def_timeout < LOGIN_TOV * 10) ?6639		def_timeout : LOGIN_TOV;6640	ddb_entry->default_time2wait =6641		le16_to_cpu(ddb_entry->fw_ddb_entry.iscsi_def_time2wait);6642 6643	if (ql4xdisablesysfsboot &&6644	    (idx == ha->pri_ddb_idx || idx == ha->sec_ddb_idx))6645		set_bit(DF_BOOT_TGT, &ddb_entry->flags);6646}6647 6648static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha)6649{6650	uint32_t idx = 0;6651	uint32_t ip_idx[IP_ADDR_COUNT] = {0, 1, 2, 3}; /* 4 IP interfaces */6652	uint32_t sts[MBOX_REG_COUNT];6653	uint32_t ip_state;6654	unsigned long wtime;6655	int ret;6656 6657	wtime = jiffies + (HZ * IP_CONFIG_TOV);6658	do {6659		for (idx = 0; idx < IP_ADDR_COUNT; idx++) {6660			if (ip_idx[idx] == -1)6661				continue;6662 6663			ret = qla4xxx_get_ip_state(ha, 0, ip_idx[idx], sts);6664 6665			if (ret == QLA_ERROR) {6666				ip_idx[idx] = -1;6667				continue;6668			}6669 6670			ip_state = (sts[1] & IP_STATE_MASK) >> IP_STATE_SHIFT;6671 6672			DEBUG2(ql4_printk(KERN_INFO, ha,6673					  "Waiting for IP state for idx = %d, state = 0x%x\n",6674					  ip_idx[idx], ip_state));6675			if (ip_state == IP_ADDRSTATE_UNCONFIGURED ||6676			    ip_state == IP_ADDRSTATE_INVALID ||6677			    ip_state == IP_ADDRSTATE_PREFERRED ||6678			    ip_state == IP_ADDRSTATE_DEPRICATED ||6679			    ip_state == IP_ADDRSTATE_DISABLING)6680				ip_idx[idx] = -1;6681		}6682 6683		/* Break if all IP states checked */6684		if ((ip_idx[0] == -1) &&6685		    (ip_idx[1] == -1) &&6686		    (ip_idx[2] == -1) &&6687		    (ip_idx[3] == -1))6688			break;6689		schedule_timeout_uninterruptible(HZ);6690	} while (time_after(wtime, jiffies));6691}6692 6693static int qla4xxx_cmp_fw_stentry(struct dev_db_entry *fw_ddb_entry,6694				  struct dev_db_entry *flash_ddb_entry)6695{6696	uint16_t options = 0;6697	size_t ip_len = IP_ADDR_LEN;6698 6699	options = le16_to_cpu(fw_ddb_entry->options);6700	if (options & DDB_OPT_IPV6_DEVICE)6701		ip_len = IPv6_ADDR_LEN;6702 6703	if (memcmp(fw_ddb_entry->ip_addr, flash_ddb_entry->ip_addr, ip_len))6704		return QLA_ERROR;6705 6706	if (memcmp(&fw_ddb_entry->isid[0], &flash_ddb_entry->isid[0],6707		   sizeof(fw_ddb_entry->isid)))6708		return QLA_ERROR;6709 6710	if (memcmp(&fw_ddb_entry->port, &flash_ddb_entry->port,6711		   sizeof(fw_ddb_entry->port)))6712		return QLA_ERROR;6713 6714	return QLA_SUCCESS;6715}6716 6717static int qla4xxx_find_flash_st_idx(struct scsi_qla_host *ha,6718				     struct dev_db_entry *fw_ddb_entry,6719				     uint32_t fw_idx, uint32_t *flash_index)6720{6721	struct dev_db_entry *flash_ddb_entry;6722	dma_addr_t flash_ddb_entry_dma;6723	uint32_t idx = 0;6724	int max_ddbs;6725	int ret = QLA_ERROR, status;6726 6727	max_ddbs =  is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :6728				     MAX_DEV_DB_ENTRIES;6729 6730	flash_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,6731					 &flash_ddb_entry_dma);6732	if (flash_ddb_entry == NULL || fw_ddb_entry == NULL) {6733		ql4_printk(KERN_ERR, ha, "Out of memory\n");6734		goto exit_find_st_idx;6735	}6736 6737	status = qla4xxx_flashdb_by_index(ha, flash_ddb_entry,6738					  flash_ddb_entry_dma, fw_idx);6739	if (status == QLA_SUCCESS) {6740		status = qla4xxx_cmp_fw_stentry(fw_ddb_entry, flash_ddb_entry);6741		if (status == QLA_SUCCESS) {6742			*flash_index = fw_idx;6743			ret = QLA_SUCCESS;6744			goto exit_find_st_idx;6745		}6746	}6747 6748	for (idx = 0; idx < max_ddbs; idx++) {6749		status = qla4xxx_flashdb_by_index(ha, flash_ddb_entry,6750						  flash_ddb_entry_dma, idx);6751		if (status == QLA_ERROR)6752			continue;6753 6754		status = qla4xxx_cmp_fw_stentry(fw_ddb_entry, flash_ddb_entry);6755		if (status == QLA_SUCCESS) {6756			*flash_index = idx;6757			ret = QLA_SUCCESS;6758			goto exit_find_st_idx;6759		}6760	}6761 6762	if (idx == max_ddbs)6763		ql4_printk(KERN_ERR, ha, "Failed to find ST [%d] in flash\n",6764			   fw_idx);6765 6766exit_find_st_idx:6767	if (flash_ddb_entry)6768		dma_pool_free(ha->fw_ddb_dma_pool, flash_ddb_entry,6769			      flash_ddb_entry_dma);6770 6771	return ret;6772}6773 6774static void qla4xxx_build_st_list(struct scsi_qla_host *ha,6775				  struct list_head *list_st)6776{6777	struct qla_ddb_index  *st_ddb_idx;6778	int max_ddbs;6779	int fw_idx_size;6780	struct dev_db_entry *fw_ddb_entry;6781	dma_addr_t fw_ddb_dma;6782	int ret;6783	uint32_t idx = 0, next_idx = 0;6784	uint32_t state = 0, conn_err = 0;6785	uint32_t flash_index = -1;6786	uint16_t conn_id = 0;6787 6788	fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,6789				      &fw_ddb_dma);6790	if (fw_ddb_entry == NULL) {6791		DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n"));6792		goto exit_st_list;6793	}6794 6795	max_ddbs =  is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :6796				     MAX_DEV_DB_ENTRIES;6797	fw_idx_size = sizeof(struct qla_ddb_index);6798 6799	for (idx = 0; idx < max_ddbs; idx = next_idx) {6800		ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, fw_ddb_dma,6801					      NULL, &next_idx, &state,6802					      &conn_err, NULL, &conn_id);6803		if (ret == QLA_ERROR)6804			break;6805 6806		/* Ignore DDB if invalid state (unassigned) */6807		if (state == DDB_DS_UNASSIGNED)6808			goto continue_next_st;6809 6810		/* Check if ST, add to the list_st */6811		if (strlen((char *) fw_ddb_entry->iscsi_name) != 0)6812			goto continue_next_st;6813 6814		st_ddb_idx = vzalloc(fw_idx_size);6815		if (!st_ddb_idx)6816			break;6817 6818		ret = qla4xxx_find_flash_st_idx(ha, fw_ddb_entry, idx,6819						&flash_index);6820		if (ret == QLA_ERROR) {6821			ql4_printk(KERN_ERR, ha,6822				   "No flash entry for ST at idx [%d]\n", idx);6823			st_ddb_idx->flash_ddb_idx = idx;6824		} else {6825			ql4_printk(KERN_INFO, ha,6826				   "ST at idx [%d] is stored at flash [%d]\n",6827				   idx, flash_index);6828			st_ddb_idx->flash_ddb_idx = flash_index;6829		}6830 6831		st_ddb_idx->fw_ddb_idx = idx;6832 6833		list_add_tail(&st_ddb_idx->list, list_st);6834continue_next_st:6835		if (next_idx == 0)6836			break;6837	}6838 6839exit_st_list:6840	if (fw_ddb_entry)6841		dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);6842}6843 6844/**6845 * qla4xxx_remove_failed_ddb - Remove inactive or failed ddb from list6846 * @ha: pointer to adapter structure6847 * @list_ddb: List from which failed ddb to be removed6848 *6849 * Iterate over the list of DDBs and find and remove DDBs that are either in6850 * no connection active state or failed state6851 **/6852static void qla4xxx_remove_failed_ddb(struct scsi_qla_host *ha,6853				      struct list_head *list_ddb)6854{6855	struct qla_ddb_index  *ddb_idx, *ddb_idx_tmp;6856	uint32_t next_idx = 0;6857	uint32_t state = 0, conn_err = 0;6858	int ret;6859 6860	list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, list_ddb, list) {6861		ret = qla4xxx_get_fwddb_entry(ha, ddb_idx->fw_ddb_idx,6862					      NULL, 0, NULL, &next_idx, &state,6863					      &conn_err, NULL, NULL);6864		if (ret == QLA_ERROR)6865			continue;6866 6867		if (state == DDB_DS_NO_CONNECTION_ACTIVE ||6868		    state == DDB_DS_SESSION_FAILED) {6869			list_del_init(&ddb_idx->list);6870			vfree(ddb_idx);6871		}6872	}6873}6874 6875static void qla4xxx_update_sess_disc_idx(struct scsi_qla_host *ha,6876					 struct ddb_entry *ddb_entry,6877					 struct dev_db_entry *fw_ddb_entry)6878{6879	struct iscsi_cls_session *cls_sess;6880	struct iscsi_session *sess;6881	uint32_t max_ddbs = 0;6882	uint16_t ddb_link = -1;6883 6884	max_ddbs =  is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :6885				     MAX_DEV_DB_ENTRIES;6886 6887	cls_sess = ddb_entry->sess;6888	sess = cls_sess->dd_data;6889 6890	ddb_link = le16_to_cpu(fw_ddb_entry->ddb_link);6891	if (ddb_link < max_ddbs)6892		sess->discovery_parent_idx = ddb_link;6893	else6894		sess->discovery_parent_idx = DDB_NO_LINK;6895}6896 6897static int qla4xxx_sess_conn_setup(struct scsi_qla_host *ha,6898				   struct dev_db_entry *fw_ddb_entry,6899				   int is_reset, uint16_t idx)6900{6901	struct iscsi_cls_session *cls_sess;6902	struct iscsi_session *sess;6903	struct iscsi_cls_conn *cls_conn;6904	struct iscsi_endpoint *ep;6905	uint16_t cmds_max = 32;6906	uint16_t conn_id = 0;6907	uint32_t initial_cmdsn = 0;6908	int ret = QLA_SUCCESS;6909 6910	struct ddb_entry *ddb_entry = NULL;6911 6912	/* Create session object, with INVALID_ENTRY,6913	 * the targer_id would get set when we issue the login6914	 */6915	cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, ha->host,6916				       cmds_max, sizeof(struct ddb_entry),6917				       sizeof(struct ql4_task_data),6918				       initial_cmdsn, INVALID_ENTRY);6919	if (!cls_sess) {6920		ret = QLA_ERROR;6921		goto exit_setup;6922	}6923 6924	/*6925	 * so calling module_put function to decrement the6926	 * reference count.6927	 **/6928	module_put(qla4xxx_iscsi_transport.owner);6929	sess = cls_sess->dd_data;6930	ddb_entry = sess->dd_data;6931	ddb_entry->sess = cls_sess;6932 6933	cls_sess->recovery_tmo = ql4xsess_recovery_tmo;6934	memcpy(&ddb_entry->fw_ddb_entry, fw_ddb_entry,6935	       sizeof(struct dev_db_entry));6936 6937	qla4xxx_setup_flash_ddb_entry(ha, ddb_entry, idx);6938 6939	cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn), conn_id);6940 6941	if (!cls_conn) {6942		ret = QLA_ERROR;6943		goto exit_setup;6944	}6945 6946	ddb_entry->conn = cls_conn;6947 6948	/* Setup ep, for displaying attributes in sysfs */6949	ep = qla4xxx_get_ep_fwdb(ha, fw_ddb_entry);6950	if (ep) {6951		ep->conn = cls_conn;6952		cls_conn->ep = ep;6953	} else {6954		DEBUG2(ql4_printk(KERN_ERR, ha, "Unable to get ep\n"));6955		ret = QLA_ERROR;6956		goto exit_setup;6957	}6958 6959	/* Update sess/conn params */6960	qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, cls_conn);6961	qla4xxx_update_sess_disc_idx(ha, ddb_entry, fw_ddb_entry);6962 6963	if (is_reset == RESET_ADAPTER) {6964		iscsi_block_session(cls_sess);6965		/* Use the relogin path to discover new devices6966		 *  by short-circuiting the logic of setting6967		 *  timer to relogin - instead set the flags6968		 *  to initiate login right away.6969		 */6970		set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);6971		set_bit(DF_RELOGIN, &ddb_entry->flags);6972	}6973 6974exit_setup:6975	return ret;6976}6977 6978static void qla4xxx_update_fw_ddb_link(struct scsi_qla_host *ha,6979				       struct list_head *list_ddb,6980				       struct dev_db_entry *fw_ddb_entry)6981{6982	struct qla_ddb_index  *ddb_idx, *ddb_idx_tmp;6983	uint16_t ddb_link;6984 6985	ddb_link = le16_to_cpu(fw_ddb_entry->ddb_link);6986 6987	list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, list_ddb, list) {6988		if (ddb_idx->fw_ddb_idx == ddb_link) {6989			DEBUG2(ql4_printk(KERN_INFO, ha,6990					  "Updating NT parent idx from [%d] to [%d]\n",6991					  ddb_link, ddb_idx->flash_ddb_idx));6992			fw_ddb_entry->ddb_link =6993					    cpu_to_le16(ddb_idx->flash_ddb_idx);6994			return;6995		}6996	}6997}6998 6999static void qla4xxx_build_nt_list(struct scsi_qla_host *ha,7000				  struct list_head *list_nt,7001				  struct list_head *list_st,7002				  int is_reset)7003{7004	struct dev_db_entry *fw_ddb_entry;7005	struct ddb_entry *ddb_entry = NULL;7006	dma_addr_t fw_ddb_dma;7007	int max_ddbs;7008	int fw_idx_size;7009	int ret;7010	uint32_t idx = 0, next_idx = 0;7011	uint32_t state = 0, conn_err = 0;7012	uint32_t ddb_idx = -1;7013	uint16_t conn_id = 0;7014	uint16_t ddb_link = -1;7015	struct qla_ddb_index  *nt_ddb_idx;7016 7017	fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,7018				      &fw_ddb_dma);7019	if (fw_ddb_entry == NULL) {7020		DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n"));7021		goto exit_nt_list;7022	}7023	max_ddbs =  is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :7024				     MAX_DEV_DB_ENTRIES;7025	fw_idx_size = sizeof(struct qla_ddb_index);7026 7027	for (idx = 0; idx < max_ddbs; idx = next_idx) {7028		ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, fw_ddb_dma,7029					      NULL, &next_idx, &state,7030					      &conn_err, NULL, &conn_id);7031		if (ret == QLA_ERROR)7032			break;7033 7034		if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS)7035			goto continue_next_nt;7036 7037		/* Check if NT, then add to list it */7038		if (strlen((char *) fw_ddb_entry->iscsi_name) == 0)7039			goto continue_next_nt;7040 7041		ddb_link = le16_to_cpu(fw_ddb_entry->ddb_link);7042		if (ddb_link < max_ddbs)7043			qla4xxx_update_fw_ddb_link(ha, list_st, fw_ddb_entry);7044 7045		if (!(state == DDB_DS_NO_CONNECTION_ACTIVE ||7046		    state == DDB_DS_SESSION_FAILED) &&7047		    (is_reset == INIT_ADAPTER))7048			goto continue_next_nt;7049 7050		DEBUG2(ql4_printk(KERN_INFO, ha,7051				  "Adding  DDB to session = 0x%x\n", idx));7052 7053		if (is_reset == INIT_ADAPTER) {7054			nt_ddb_idx = vmalloc(fw_idx_size);7055			if (!nt_ddb_idx)7056				break;7057 7058			nt_ddb_idx->fw_ddb_idx = idx;7059 7060			/* Copy original isid as it may get updated in function7061			 * qla4xxx_update_isid(). We need original isid in7062			 * function qla4xxx_compare_tuple_ddb to find duplicate7063			 * target */7064			memcpy(&nt_ddb_idx->flash_isid[0],7065			       &fw_ddb_entry->isid[0],7066			       sizeof(nt_ddb_idx->flash_isid));7067 7068			ret = qla4xxx_is_flash_ddb_exists(ha, list_nt,7069							  fw_ddb_entry);7070			if (ret == QLA_SUCCESS) {7071				/* free nt_ddb_idx and do not add to list_nt */7072				vfree(nt_ddb_idx);7073				goto continue_next_nt;7074			}7075 7076			/* Copy updated isid */7077			memcpy(&nt_ddb_idx->fw_ddb, fw_ddb_entry,7078			       sizeof(struct dev_db_entry));7079 7080			list_add_tail(&nt_ddb_idx->list, list_nt);7081		} else if (is_reset == RESET_ADAPTER) {7082			ret = qla4xxx_is_session_exists(ha, fw_ddb_entry,7083							&ddb_idx);7084			if (ret == QLA_SUCCESS) {7085				ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha,7086								       ddb_idx);7087				if (ddb_entry != NULL)7088					qla4xxx_update_sess_disc_idx(ha,7089								     ddb_entry,7090								  fw_ddb_entry);7091				goto continue_next_nt;7092			}7093		}7094 7095		ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, is_reset, idx);7096		if (ret == QLA_ERROR)7097			goto exit_nt_list;7098 7099continue_next_nt:7100		if (next_idx == 0)7101			break;7102	}7103 7104exit_nt_list:7105	if (fw_ddb_entry)7106		dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);7107}7108 7109static void qla4xxx_build_new_nt_list(struct scsi_qla_host *ha,7110				      struct list_head *list_nt,7111				      uint16_t target_id)7112{7113	struct dev_db_entry *fw_ddb_entry;7114	dma_addr_t fw_ddb_dma;7115	int max_ddbs;7116	int fw_idx_size;7117	int ret;7118	uint32_t idx = 0, next_idx = 0;7119	uint32_t state = 0, conn_err = 0;7120	uint16_t conn_id = 0;7121	struct qla_ddb_index  *nt_ddb_idx;7122 7123	fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,7124				      &fw_ddb_dma);7125	if (fw_ddb_entry == NULL) {7126		DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n"));7127		goto exit_new_nt_list;7128	}7129	max_ddbs =  is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :7130				     MAX_DEV_DB_ENTRIES;7131	fw_idx_size = sizeof(struct qla_ddb_index);7132 7133	for (idx = 0; idx < max_ddbs; idx = next_idx) {7134		ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, fw_ddb_dma,7135					      NULL, &next_idx, &state,7136					      &conn_err, NULL, &conn_id);7137		if (ret == QLA_ERROR)7138			break;7139 7140		/* Check if NT, then add it to list */7141		if (strlen((char *)fw_ddb_entry->iscsi_name) == 0)7142			goto continue_next_new_nt;7143 7144		if (!(state == DDB_DS_NO_CONNECTION_ACTIVE))7145			goto continue_next_new_nt;7146 7147		DEBUG2(ql4_printk(KERN_INFO, ha,7148				  "Adding  DDB to session = 0x%x\n", idx));7149 7150		nt_ddb_idx = vmalloc(fw_idx_size);7151		if (!nt_ddb_idx)7152			break;7153 7154		nt_ddb_idx->fw_ddb_idx = idx;7155 7156		ret = qla4xxx_is_session_exists(ha, fw_ddb_entry, NULL);7157		if (ret == QLA_SUCCESS) {7158			/* free nt_ddb_idx and do not add to list_nt */7159			vfree(nt_ddb_idx);7160			goto continue_next_new_nt;7161		}7162 7163		if (target_id < max_ddbs)7164			fw_ddb_entry->ddb_link = cpu_to_le16(target_id);7165 7166		list_add_tail(&nt_ddb_idx->list, list_nt);7167 7168		ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, RESET_ADAPTER,7169					      idx);7170		if (ret == QLA_ERROR)7171			goto exit_new_nt_list;7172 7173continue_next_new_nt:7174		if (next_idx == 0)7175			break;7176	}7177 7178exit_new_nt_list:7179	if (fw_ddb_entry)7180		dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);7181}7182 7183/**7184 * qla4xxx_sysfs_ddb_is_non_persistent - check for non-persistence of ddb entry7185 * @dev: dev associated with the sysfs entry7186 * @data: pointer to flashnode session object7187 *7188 * Returns:7189 *	1: if flashnode entry is non-persistent7190 *	0: if flashnode entry is persistent7191 **/7192static int qla4xxx_sysfs_ddb_is_non_persistent(struct device *dev, void *data)7193{7194	struct iscsi_bus_flash_session *fnode_sess;7195 7196	if (!iscsi_flashnode_bus_match(dev, NULL))7197		return 0;7198 7199	fnode_sess = iscsi_dev_to_flash_session(dev);7200 7201	return (fnode_sess->flash_state == DEV_DB_NON_PERSISTENT);7202}7203 7204/**7205 * qla4xxx_sysfs_ddb_tgt_create - Create sysfs entry for target7206 * @ha: pointer to host7207 * @fw_ddb_entry: flash ddb data7208 * @idx: target index7209 * @user: if set then this call is made from userland else from kernel7210 *7211 * Returns:7212 * On sucess: QLA_SUCCESS7213 * On failure: QLA_ERROR7214 *7215 * This create separate sysfs entries for session and connection attributes of7216 * the given fw ddb entry.7217 * If this is invoked as a result of a userspace call then the entry is marked7218 * as nonpersistent using flash_state field.7219 **/7220static int qla4xxx_sysfs_ddb_tgt_create(struct scsi_qla_host *ha,7221					struct dev_db_entry *fw_ddb_entry,7222					uint16_t *idx, int user)7223{7224	struct iscsi_bus_flash_session *fnode_sess = NULL;7225	struct iscsi_bus_flash_conn *fnode_conn = NULL;7226	int rc = QLA_ERROR;7227 7228	fnode_sess = iscsi_create_flashnode_sess(ha->host, *idx,7229						 &qla4xxx_iscsi_transport, 0);7230	if (!fnode_sess) {7231		ql4_printk(KERN_ERR, ha,7232			   "%s: Unable to create session sysfs entry for flashnode %d of host%lu\n",7233			   __func__, *idx, ha->host_no);7234		goto exit_tgt_create;7235	}7236 7237	fnode_conn = iscsi_create_flashnode_conn(ha->host, fnode_sess,7238						 &qla4xxx_iscsi_transport, 0);7239	if (!fnode_conn) {7240		ql4_printk(KERN_ERR, ha,7241			   "%s: Unable to create conn sysfs entry for flashnode %d of host%lu\n",7242			   __func__, *idx, ha->host_no);7243		goto free_sess;7244	}7245 7246	if (user) {7247		fnode_sess->flash_state = DEV_DB_NON_PERSISTENT;7248	} else {7249		fnode_sess->flash_state = DEV_DB_PERSISTENT;7250 7251		if (*idx == ha->pri_ddb_idx || *idx == ha->sec_ddb_idx)7252			fnode_sess->is_boot_target = 1;7253		else7254			fnode_sess->is_boot_target = 0;7255	}7256 7257	rc = qla4xxx_copy_from_fwddb_param(fnode_sess, fnode_conn,7258					   fw_ddb_entry);7259	if (rc)7260		goto free_sess;7261 7262	ql4_printk(KERN_INFO, ha, "%s: sysfs entry %s created\n",7263		   __func__, fnode_sess->dev.kobj.name);7264 7265	ql4_printk(KERN_INFO, ha, "%s: sysfs entry %s created\n",7266		   __func__, fnode_conn->dev.kobj.name);7267 7268	return QLA_SUCCESS;7269 7270free_sess:7271	iscsi_destroy_flashnode_sess(fnode_sess);7272 7273exit_tgt_create:7274	return QLA_ERROR;7275}7276 7277/**7278 * qla4xxx_sysfs_ddb_add - Add new ddb entry in flash7279 * @shost: pointer to host7280 * @buf: type of ddb entry (ipv4/ipv6)7281 * @len: length of buf7282 *7283 * This creates new ddb entry in the flash by finding first free index and7284 * storing default ddb there. And then create sysfs entry for the new ddb entry.7285 **/7286static int qla4xxx_sysfs_ddb_add(struct Scsi_Host *shost, const char *buf,7287				 int len)7288{7289	struct scsi_qla_host *ha = to_qla_host(shost);7290	struct dev_db_entry *fw_ddb_entry = NULL;7291	dma_addr_t fw_ddb_entry_dma;7292	struct device *dev;7293	uint16_t idx = 0;7294	uint16_t max_ddbs = 0;7295	uint32_t options = 0;7296	uint32_t rval = QLA_ERROR;7297 7298	if (strncasecmp(PORTAL_TYPE_IPV4, buf, 4) &&7299	    strncasecmp(PORTAL_TYPE_IPV6, buf, 4)) {7300		DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Invalid portal type\n",7301				  __func__));7302		goto exit_ddb_add;7303	}7304 7305	max_ddbs =  is_qla40XX(ha) ? MAX_PRST_DEV_DB_ENTRIES :7306				     MAX_DEV_DB_ENTRIES;7307 7308	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),7309					  &fw_ddb_entry_dma, GFP_KERNEL);7310	if (!fw_ddb_entry) {7311		DEBUG2(ql4_printk(KERN_ERR, ha,7312				  "%s: Unable to allocate dma buffer\n",7313				  __func__));7314		goto exit_ddb_add;7315	}7316 7317	dev = iscsi_find_flashnode_sess(ha->host, NULL,7318					qla4xxx_sysfs_ddb_is_non_persistent);7319	if (dev) {7320		ql4_printk(KERN_ERR, ha,7321			   "%s: A non-persistent entry %s found\n",7322			   __func__, dev->kobj.name);7323		put_device(dev);7324		goto exit_ddb_add;7325	}7326 7327	/* Index 0 and 1 are reserved for boot target entries */7328	for (idx = 2; idx < max_ddbs; idx++) {7329		if (qla4xxx_flashdb_by_index(ha, fw_ddb_entry,7330					     fw_ddb_entry_dma, idx))7331			break;7332	}7333 7334	if (idx == max_ddbs)7335		goto exit_ddb_add;7336 7337	if (!strncasecmp("ipv6", buf, 4))7338		options |= IPV6_DEFAULT_DDB_ENTRY;7339 7340	rval = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma);7341	if (rval == QLA_ERROR)7342		goto exit_ddb_add;7343 7344	rval = qla4xxx_sysfs_ddb_tgt_create(ha, fw_ddb_entry, &idx, 1);7345 7346exit_ddb_add:7347	if (fw_ddb_entry)7348		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),7349				  fw_ddb_entry, fw_ddb_entry_dma);7350	if (rval == QLA_SUCCESS)7351		return idx;7352	else7353		return -EIO;7354}7355 7356/**7357 * qla4xxx_sysfs_ddb_apply - write the target ddb contents to Flash7358 * @fnode_sess: pointer to session attrs of flash ddb entry7359 * @fnode_conn: pointer to connection attrs of flash ddb entry7360 *7361 * This writes the contents of target ddb buffer to Flash with a valid cookie7362 * value in order to make the ddb entry persistent.7363 **/7364static int  qla4xxx_sysfs_ddb_apply(struct iscsi_bus_flash_session *fnode_sess,7365				    struct iscsi_bus_flash_conn *fnode_conn)7366{7367	struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);7368	struct scsi_qla_host *ha = to_qla_host(shost);7369	uint32_t dev_db_start_offset = FLASH_OFFSET_DB_INFO;7370	struct dev_db_entry *fw_ddb_entry = NULL;7371	dma_addr_t fw_ddb_entry_dma;7372	uint32_t options = 0;7373	int rval = 0;7374 7375	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),7376					  &fw_ddb_entry_dma, GFP_KERNEL);7377	if (!fw_ddb_entry) {7378		DEBUG2(ql4_printk(KERN_ERR, ha,7379				  "%s: Unable to allocate dma buffer\n",7380				  __func__));7381		rval = -ENOMEM;7382		goto exit_ddb_apply;7383	}7384 7385	if (!strncasecmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4))7386		options |= IPV6_DEFAULT_DDB_ENTRY;7387 7388	rval = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma);7389	if (rval == QLA_ERROR)7390		goto exit_ddb_apply;7391 7392	dev_db_start_offset += (fnode_sess->target_id *7393				sizeof(*fw_ddb_entry));7394 7395	qla4xxx_copy_to_fwddb_param(fnode_sess, fnode_conn, fw_ddb_entry);7396	fw_ddb_entry->cookie = DDB_VALID_COOKIE;7397 7398	rval = qla4xxx_set_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,7399				 sizeof(*fw_ddb_entry), FLASH_OPT_RMW_COMMIT);7400 7401	if (rval == QLA_SUCCESS) {7402		fnode_sess->flash_state = DEV_DB_PERSISTENT;7403		ql4_printk(KERN_INFO, ha,7404			   "%s: flash node %u of host %lu written to flash\n",7405			   __func__, fnode_sess->target_id, ha->host_no);7406	} else {7407		rval = -EIO;7408		ql4_printk(KERN_ERR, ha,7409			   "%s: Error while writing flash node %u of host %lu to flash\n",7410			   __func__, fnode_sess->target_id, ha->host_no);7411	}7412 7413exit_ddb_apply:7414	if (fw_ddb_entry)7415		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),7416				  fw_ddb_entry, fw_ddb_entry_dma);7417	return rval;7418}7419 7420static ssize_t qla4xxx_sysfs_ddb_conn_open(struct scsi_qla_host *ha,7421					   struct dev_db_entry *fw_ddb_entry,7422					   uint16_t idx)7423{7424	struct dev_db_entry *ddb_entry = NULL;7425	dma_addr_t ddb_entry_dma;7426	unsigned long wtime;7427	uint32_t mbx_sts = 0;7428	uint32_t state = 0, conn_err = 0;7429	uint16_t tmo = 0;7430	int ret = 0;7431 7432	ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*ddb_entry),7433				       &ddb_entry_dma, GFP_KERNEL);7434	if (!ddb_entry) {7435		DEBUG2(ql4_printk(KERN_ERR, ha,7436				  "%s: Unable to allocate dma buffer\n",7437				  __func__));7438		return QLA_ERROR;7439	}7440 7441	memcpy(ddb_entry, fw_ddb_entry, sizeof(*ddb_entry));7442 7443	ret = qla4xxx_set_ddb_entry(ha, idx, ddb_entry_dma, &mbx_sts);7444	if (ret != QLA_SUCCESS) {7445		DEBUG2(ql4_printk(KERN_ERR, ha,7446				  "%s: Unable to set ddb entry for index %d\n",7447				  __func__, idx));7448		goto exit_ddb_conn_open;7449	}7450 7451	qla4xxx_conn_open(ha, idx);7452 7453	/* To ensure that sendtargets is done, wait for at least 12 secs */7454	tmo = ((ha->def_timeout > LOGIN_TOV) &&7455	       (ha->def_timeout < LOGIN_TOV * 10) ?7456	       ha->def_timeout : LOGIN_TOV);7457 7458	DEBUG2(ql4_printk(KERN_INFO, ha,7459			  "Default time to wait for login to ddb %d\n", tmo));7460 7461	wtime = jiffies + (HZ * tmo);7462	do {7463		ret = qla4xxx_get_fwddb_entry(ha, idx, NULL, 0, NULL,7464					      NULL, &state, &conn_err, NULL,7465					      NULL);7466		if (ret == QLA_ERROR)7467			continue;7468 7469		if (state == DDB_DS_NO_CONNECTION_ACTIVE ||7470		    state == DDB_DS_SESSION_FAILED)7471			break;7472 7473		schedule_timeout_uninterruptible(HZ / 10);7474	} while (time_after(wtime, jiffies));7475 7476exit_ddb_conn_open:7477	if (ddb_entry)7478		dma_free_coherent(&ha->pdev->dev, sizeof(*ddb_entry),7479				  ddb_entry, ddb_entry_dma);7480	return ret;7481}7482 7483static int qla4xxx_ddb_login_st(struct scsi_qla_host *ha,7484				struct dev_db_entry *fw_ddb_entry,7485				uint16_t target_id)7486{7487	struct qla_ddb_index *ddb_idx, *ddb_idx_tmp;7488	struct list_head list_nt;7489	uint16_t ddb_index;7490	int ret = 0;7491 7492	if (test_bit(AF_ST_DISCOVERY_IN_PROGRESS, &ha->flags)) {7493		ql4_printk(KERN_WARNING, ha,7494			   "%s: A discovery already in progress!\n", __func__);7495		return QLA_ERROR;7496	}7497 7498	INIT_LIST_HEAD(&list_nt);7499 7500	set_bit(AF_ST_DISCOVERY_IN_PROGRESS, &ha->flags);7501 7502	ret = qla4xxx_get_ddb_index(ha, &ddb_index);7503	if (ret == QLA_ERROR)7504		goto exit_login_st_clr_bit;7505 7506	ret = qla4xxx_sysfs_ddb_conn_open(ha, fw_ddb_entry, ddb_index);7507	if (ret == QLA_ERROR)7508		goto exit_login_st;7509 7510	qla4xxx_build_new_nt_list(ha, &list_nt, target_id);7511 7512	list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, &list_nt, list) {7513		list_del_init(&ddb_idx->list);7514		qla4xxx_clear_ddb_entry(ha, ddb_idx->fw_ddb_idx);7515		vfree(ddb_idx);7516	}7517 7518exit_login_st:7519	if (qla4xxx_clear_ddb_entry(ha, ddb_index) == QLA_ERROR) {7520		ql4_printk(KERN_ERR, ha,7521			   "Unable to clear DDB index = 0x%x\n", ddb_index);7522	}7523 7524	clear_bit(ddb_index, ha->ddb_idx_map);7525 7526exit_login_st_clr_bit:7527	clear_bit(AF_ST_DISCOVERY_IN_PROGRESS, &ha->flags);7528	return ret;7529}7530 7531static int qla4xxx_ddb_login_nt(struct scsi_qla_host *ha,7532				struct dev_db_entry *fw_ddb_entry,7533				uint16_t idx)7534{7535	int ret = QLA_ERROR;7536 7537	ret = qla4xxx_is_session_exists(ha, fw_ddb_entry, NULL);7538	if (ret != QLA_SUCCESS)7539		ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, RESET_ADAPTER,7540					      idx);7541	else7542		ret = -EPERM;7543 7544	return ret;7545}7546 7547/**7548 * qla4xxx_sysfs_ddb_login - Login to the specified target7549 * @fnode_sess: pointer to session attrs of flash ddb entry7550 * @fnode_conn: pointer to connection attrs of flash ddb entry7551 *7552 * This logs in to the specified target7553 **/7554static int qla4xxx_sysfs_ddb_login(struct iscsi_bus_flash_session *fnode_sess,7555				   struct iscsi_bus_flash_conn *fnode_conn)7556{7557	struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);7558	struct scsi_qla_host *ha = to_qla_host(shost);7559	struct dev_db_entry *fw_ddb_entry = NULL;7560	dma_addr_t fw_ddb_entry_dma;7561	uint32_t options = 0;7562	int ret = 0;7563 7564	if (fnode_sess->flash_state == DEV_DB_NON_PERSISTENT) {7565		ql4_printk(KERN_ERR, ha,7566			   "%s: Target info is not persistent\n", __func__);7567		ret = -EIO;7568		goto exit_ddb_login;7569	}7570 7571	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),7572					  &fw_ddb_entry_dma, GFP_KERNEL);7573	if (!fw_ddb_entry) {7574		DEBUG2(ql4_printk(KERN_ERR, ha,7575				  "%s: Unable to allocate dma buffer\n",7576				  __func__));7577		ret = -ENOMEM;7578		goto exit_ddb_login;7579	}7580 7581	if (!strncasecmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4))7582		options |= IPV6_DEFAULT_DDB_ENTRY;7583 7584	ret = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma);7585	if (ret == QLA_ERROR)7586		goto exit_ddb_login;7587 7588	qla4xxx_copy_to_fwddb_param(fnode_sess, fnode_conn, fw_ddb_entry);7589	fw_ddb_entry->cookie = DDB_VALID_COOKIE;7590 7591	if (strlen((char *)fw_ddb_entry->iscsi_name) == 0)7592		ret = qla4xxx_ddb_login_st(ha, fw_ddb_entry,7593					   fnode_sess->target_id);7594	else7595		ret = qla4xxx_ddb_login_nt(ha, fw_ddb_entry,7596					   fnode_sess->target_id);7597 7598	if (ret > 0)7599		ret = -EIO;7600 7601exit_ddb_login:7602	if (fw_ddb_entry)7603		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),7604				  fw_ddb_entry, fw_ddb_entry_dma);7605	return ret;7606}7607 7608/**7609 * qla4xxx_sysfs_ddb_logout_sid - Logout session for the specified target7610 * @cls_sess: pointer to session to be logged out7611 *7612 * This performs session log out from the specified target7613 **/7614static int qla4xxx_sysfs_ddb_logout_sid(struct iscsi_cls_session *cls_sess)7615{7616	struct iscsi_session *sess;7617	struct ddb_entry *ddb_entry = NULL;7618	struct scsi_qla_host *ha;7619	struct dev_db_entry *fw_ddb_entry = NULL;7620	dma_addr_t fw_ddb_entry_dma;7621	unsigned long flags;7622	unsigned long wtime;7623	uint32_t ddb_state;7624	int options;7625	int ret = 0;7626 7627	sess = cls_sess->dd_data;7628	ddb_entry = sess->dd_data;7629	ha = ddb_entry->ha;7630 7631	if (ddb_entry->ddb_type != FLASH_DDB) {7632		ql4_printk(KERN_ERR, ha, "%s: Not a flash node session\n",7633			   __func__);7634		ret = -ENXIO;7635		goto exit_ddb_logout;7636	}7637 7638	if (test_bit(DF_BOOT_TGT, &ddb_entry->flags)) {7639		ql4_printk(KERN_ERR, ha,7640			   "%s: Logout from boot target entry is not permitted.\n",7641			   __func__);7642		ret = -EPERM;7643		goto exit_ddb_logout;7644	}7645 7646	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),7647					  &fw_ddb_entry_dma, GFP_KERNEL);7648	if (!fw_ddb_entry) {7649		ql4_printk(KERN_ERR, ha,7650			   "%s: Unable to allocate dma buffer\n", __func__);7651		ret = -ENOMEM;7652		goto exit_ddb_logout;7653	}7654 7655	if (test_and_set_bit(DF_DISABLE_RELOGIN, &ddb_entry->flags))7656		goto ddb_logout_init;7657 7658	ret = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index,7659				      fw_ddb_entry, fw_ddb_entry_dma,7660				      NULL, NULL, &ddb_state, NULL,7661				      NULL, NULL);7662	if (ret == QLA_ERROR)7663		goto ddb_logout_init;7664 7665	if (ddb_state == DDB_DS_SESSION_ACTIVE)7666		goto ddb_logout_init;7667 7668	/* wait until next relogin is triggered using DF_RELOGIN and7669	 * clear DF_RELOGIN to avoid invocation of further relogin7670	 */7671	wtime = jiffies + (HZ * RELOGIN_TOV);7672	do {7673		if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags))7674			goto ddb_logout_init;7675 7676		schedule_timeout_uninterruptible(HZ);7677	} while ((time_after(wtime, jiffies)));7678 7679ddb_logout_init:7680	atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY);7681	atomic_set(&ddb_entry->relogin_timer, 0);7682 7683	options = LOGOUT_OPTION_CLOSE_SESSION;7684	qla4xxx_session_logout_ddb(ha, ddb_entry, options);7685 7686	memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));7687	wtime = jiffies + (HZ * LOGOUT_TOV);7688	do {7689		ret = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index,7690					      fw_ddb_entry, fw_ddb_entry_dma,7691					      NULL, NULL, &ddb_state, NULL,7692					      NULL, NULL);7693		if (ret == QLA_ERROR)7694			goto ddb_logout_clr_sess;7695 7696		if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) ||7697		    (ddb_state == DDB_DS_SESSION_FAILED))7698			goto ddb_logout_clr_sess;7699 7700		schedule_timeout_uninterruptible(HZ);7701	} while ((time_after(wtime, jiffies)));7702 7703ddb_logout_clr_sess:7704	qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);7705	/*7706	 * we have decremented the reference count of the driver7707	 * when we setup the session to have the driver unload7708	 * to be seamless without actually destroying the7709	 * session7710	 **/7711	try_module_get(qla4xxx_iscsi_transport.owner);7712	iscsi_destroy_endpoint(ddb_entry->conn->ep);7713 7714	spin_lock_irqsave(&ha->hardware_lock, flags);7715	qla4xxx_free_ddb(ha, ddb_entry);7716	clear_bit(ddb_entry->fw_ddb_index, ha->ddb_idx_map);7717	spin_unlock_irqrestore(&ha->hardware_lock, flags);7718 7719	iscsi_session_teardown(ddb_entry->sess);7720 7721	clear_bit(DF_DISABLE_RELOGIN, &ddb_entry->flags);7722	ret = QLA_SUCCESS;7723 7724exit_ddb_logout:7725	if (fw_ddb_entry)7726		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),7727				  fw_ddb_entry, fw_ddb_entry_dma);7728	return ret;7729}7730 7731/**7732 * qla4xxx_sysfs_ddb_logout - Logout from the specified target7733 * @fnode_sess: pointer to session attrs of flash ddb entry7734 * @fnode_conn: pointer to connection attrs of flash ddb entry7735 *7736 * This performs log out from the specified target7737 **/7738static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess,7739				    struct iscsi_bus_flash_conn *fnode_conn)7740{7741	struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);7742	struct scsi_qla_host *ha = to_qla_host(shost);7743	struct ql4_tuple_ddb *flash_tddb = NULL;7744	struct ql4_tuple_ddb *tmp_tddb = NULL;7745	struct dev_db_entry *fw_ddb_entry = NULL;7746	struct ddb_entry *ddb_entry = NULL;7747	dma_addr_t fw_ddb_dma;7748	uint32_t next_idx = 0;7749	uint32_t state = 0, conn_err = 0;7750	uint16_t conn_id = 0;7751	int idx, index;7752	int status, ret = 0;7753 7754	fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,7755				      &fw_ddb_dma);7756	if (fw_ddb_entry == NULL) {7757		ql4_printk(KERN_ERR, ha, "%s:Out of memory\n", __func__);7758		ret = -ENOMEM;7759		goto exit_ddb_logout;7760	}7761 7762	flash_tddb = vzalloc(sizeof(*flash_tddb));7763	if (!flash_tddb) {7764		ql4_printk(KERN_WARNING, ha,7765			   "%s:Memory Allocation failed.\n", __func__);7766		ret = -ENOMEM;7767		goto exit_ddb_logout;7768	}7769 7770	tmp_tddb = vzalloc(sizeof(*tmp_tddb));7771	if (!tmp_tddb) {7772		ql4_printk(KERN_WARNING, ha,7773			   "%s:Memory Allocation failed.\n", __func__);7774		ret = -ENOMEM;7775		goto exit_ddb_logout;7776	}7777 7778	if (!fnode_sess->targetname) {7779		ql4_printk(KERN_ERR, ha,7780			   "%s:Cannot logout from SendTarget entry\n",7781			   __func__);7782		ret = -EPERM;7783		goto exit_ddb_logout;7784	}7785 7786	if (fnode_sess->is_boot_target) {7787		ql4_printk(KERN_ERR, ha,7788			   "%s: Logout from boot target entry is not permitted.\n",7789			   __func__);7790		ret = -EPERM;7791		goto exit_ddb_logout;7792	}7793 7794	strscpy(flash_tddb->iscsi_name, fnode_sess->targetname,7795		sizeof(flash_tddb->iscsi_name));7796 7797	if (!strncmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4))7798		sprintf(flash_tddb->ip_addr, "%pI6", fnode_conn->ipaddress);7799	else7800		sprintf(flash_tddb->ip_addr, "%pI4", fnode_conn->ipaddress);7801 7802	flash_tddb->tpgt = fnode_sess->tpgt;7803	flash_tddb->port = fnode_conn->port;7804 7805	COPY_ISID(flash_tddb->isid, fnode_sess->isid);7806 7807	for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) {7808		ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);7809		if (ddb_entry == NULL)7810			continue;7811 7812		if (ddb_entry->ddb_type != FLASH_DDB)7813			continue;7814 7815		index = ddb_entry->sess->target_id;7816		status = qla4xxx_get_fwddb_entry(ha, index, fw_ddb_entry,7817						 fw_ddb_dma, NULL, &next_idx,7818						 &state, &conn_err, NULL,7819						 &conn_id);7820		if (status == QLA_ERROR) {7821			ret = -ENOMEM;7822			break;7823		}7824 7825		qla4xxx_convert_param_ddb(fw_ddb_entry, tmp_tddb, NULL);7826 7827		status = qla4xxx_compare_tuple_ddb(ha, flash_tddb, tmp_tddb,7828						   true);7829		if (status == QLA_SUCCESS) {7830			ret = qla4xxx_sysfs_ddb_logout_sid(ddb_entry->sess);7831			break;7832		}7833	}7834 7835	if (idx == MAX_DDB_ENTRIES)7836		ret = -ESRCH;7837 7838exit_ddb_logout:7839	vfree(flash_tddb);7840	vfree(tmp_tddb);7841	if (fw_ddb_entry)7842		dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);7843 7844	return ret;7845}7846 7847static int7848qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,7849			    int param, char *buf)7850{7851	struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);7852	struct scsi_qla_host *ha = to_qla_host(shost);7853	struct iscsi_bus_flash_conn *fnode_conn;7854	struct ql4_chap_table chap_tbl;7855	struct device *dev;7856	int parent_type;7857	int rc = 0;7858 7859	dev = iscsi_find_flashnode_conn(fnode_sess);7860	if (!dev)7861		return -EIO;7862 7863	fnode_conn = iscsi_dev_to_flash_conn(dev);7864 7865	switch (param) {7866	case ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6:7867		rc = sprintf(buf, "%u\n", fnode_conn->is_fw_assigned_ipv6);7868		break;7869	case ISCSI_FLASHNODE_PORTAL_TYPE:7870		rc = sprintf(buf, "%s\n", fnode_sess->portal_type);7871		break;7872	case ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE:7873		rc = sprintf(buf, "%u\n", fnode_sess->auto_snd_tgt_disable);7874		break;7875	case ISCSI_FLASHNODE_DISCOVERY_SESS:7876		rc = sprintf(buf, "%u\n", fnode_sess->discovery_sess);7877		break;7878	case ISCSI_FLASHNODE_ENTRY_EN:7879		rc = sprintf(buf, "%u\n", fnode_sess->entry_state);7880		break;7881	case ISCSI_FLASHNODE_HDR_DGST_EN:7882		rc = sprintf(buf, "%u\n", fnode_conn->hdrdgst_en);7883		break;7884	case ISCSI_FLASHNODE_DATA_DGST_EN:7885		rc = sprintf(buf, "%u\n", fnode_conn->datadgst_en);7886		break;7887	case ISCSI_FLASHNODE_IMM_DATA_EN:7888		rc = sprintf(buf, "%u\n", fnode_sess->imm_data_en);7889		break;7890	case ISCSI_FLASHNODE_INITIAL_R2T_EN:7891		rc = sprintf(buf, "%u\n", fnode_sess->initial_r2t_en);7892		break;7893	case ISCSI_FLASHNODE_DATASEQ_INORDER:7894		rc = sprintf(buf, "%u\n", fnode_sess->dataseq_inorder_en);7895		break;7896	case ISCSI_FLASHNODE_PDU_INORDER:7897		rc = sprintf(buf, "%u\n", fnode_sess->pdu_inorder_en);7898		break;7899	case ISCSI_FLASHNODE_CHAP_AUTH_EN:7900		rc = sprintf(buf, "%u\n", fnode_sess->chap_auth_en);7901		break;7902	case ISCSI_FLASHNODE_SNACK_REQ_EN:7903		rc = sprintf(buf, "%u\n", fnode_conn->snack_req_en);7904		break;7905	case ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN:7906		rc = sprintf(buf, "%u\n", fnode_sess->discovery_logout_en);7907		break;7908	case ISCSI_FLASHNODE_BIDI_CHAP_EN:7909		rc = sprintf(buf, "%u\n", fnode_sess->bidi_chap_en);7910		break;7911	case ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL:7912		rc = sprintf(buf, "%u\n", fnode_sess->discovery_auth_optional);7913		break;7914	case ISCSI_FLASHNODE_ERL:7915		rc = sprintf(buf, "%u\n", fnode_sess->erl);7916		break;7917	case ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT:7918		rc = sprintf(buf, "%u\n", fnode_conn->tcp_timestamp_stat);7919		break;7920	case ISCSI_FLASHNODE_TCP_NAGLE_DISABLE:7921		rc = sprintf(buf, "%u\n", fnode_conn->tcp_nagle_disable);7922		break;7923	case ISCSI_FLASHNODE_TCP_WSF_DISABLE:7924		rc = sprintf(buf, "%u\n", fnode_conn->tcp_wsf_disable);7925		break;7926	case ISCSI_FLASHNODE_TCP_TIMER_SCALE:7927		rc = sprintf(buf, "%u\n", fnode_conn->tcp_timer_scale);7928		break;7929	case ISCSI_FLASHNODE_TCP_TIMESTAMP_EN:7930		rc = sprintf(buf, "%u\n", fnode_conn->tcp_timestamp_en);7931		break;7932	case ISCSI_FLASHNODE_IP_FRAG_DISABLE:7933		rc = sprintf(buf, "%u\n", fnode_conn->fragment_disable);7934		break;7935	case ISCSI_FLASHNODE_MAX_RECV_DLENGTH:7936		rc = sprintf(buf, "%u\n", fnode_conn->max_recv_dlength);7937		break;7938	case ISCSI_FLASHNODE_MAX_XMIT_DLENGTH:7939		rc = sprintf(buf, "%u\n", fnode_conn->max_xmit_dlength);7940		break;7941	case ISCSI_FLASHNODE_FIRST_BURST:7942		rc = sprintf(buf, "%u\n", fnode_sess->first_burst);7943		break;7944	case ISCSI_FLASHNODE_DEF_TIME2WAIT:7945		rc = sprintf(buf, "%u\n", fnode_sess->time2wait);7946		break;7947	case ISCSI_FLASHNODE_DEF_TIME2RETAIN:7948		rc = sprintf(buf, "%u\n", fnode_sess->time2retain);7949		break;7950	case ISCSI_FLASHNODE_MAX_R2T:7951		rc = sprintf(buf, "%u\n", fnode_sess->max_r2t);7952		break;7953	case ISCSI_FLASHNODE_KEEPALIVE_TMO:7954		rc = sprintf(buf, "%u\n", fnode_conn->keepalive_timeout);7955		break;7956	case ISCSI_FLASHNODE_ISID:7957		rc = sprintf(buf, "%pm\n", fnode_sess->isid);7958		break;7959	case ISCSI_FLASHNODE_TSID:7960		rc = sprintf(buf, "%u\n", fnode_sess->tsid);7961		break;7962	case ISCSI_FLASHNODE_PORT:7963		rc = sprintf(buf, "%d\n", fnode_conn->port);7964		break;7965	case ISCSI_FLASHNODE_MAX_BURST:7966		rc = sprintf(buf, "%u\n", fnode_sess->max_burst);7967		break;7968	case ISCSI_FLASHNODE_DEF_TASKMGMT_TMO:7969		rc = sprintf(buf, "%u\n",7970			     fnode_sess->default_taskmgmt_timeout);7971		break;7972	case ISCSI_FLASHNODE_IPADDR:7973		if (!strncmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4))7974			rc = sprintf(buf, "%pI6\n", fnode_conn->ipaddress);7975		else7976			rc = sprintf(buf, "%pI4\n", fnode_conn->ipaddress);7977		break;7978	case ISCSI_FLASHNODE_ALIAS:7979		if (fnode_sess->targetalias)7980			rc = sprintf(buf, "%s\n", fnode_sess->targetalias);7981		else7982			rc = sprintf(buf, "\n");7983		break;7984	case ISCSI_FLASHNODE_REDIRECT_IPADDR:7985		if (!strncmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4))7986			rc = sprintf(buf, "%pI6\n",7987				     fnode_conn->redirect_ipaddr);7988		else7989			rc = sprintf(buf, "%pI4\n",7990				     fnode_conn->redirect_ipaddr);7991		break;7992	case ISCSI_FLASHNODE_MAX_SEGMENT_SIZE:7993		rc = sprintf(buf, "%u\n", fnode_conn->max_segment_size);7994		break;7995	case ISCSI_FLASHNODE_LOCAL_PORT:7996		rc = sprintf(buf, "%u\n", fnode_conn->local_port);7997		break;7998	case ISCSI_FLASHNODE_IPV4_TOS:7999		rc = sprintf(buf, "%u\n", fnode_conn->ipv4_tos);8000		break;8001	case ISCSI_FLASHNODE_IPV6_TC:8002		if (!strncmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4))8003			rc = sprintf(buf, "%u\n",8004				     fnode_conn->ipv6_traffic_class);8005		else8006			rc = sprintf(buf, "\n");8007		break;8008	case ISCSI_FLASHNODE_IPV6_FLOW_LABEL:8009		rc = sprintf(buf, "%u\n", fnode_conn->ipv6_flow_label);8010		break;8011	case ISCSI_FLASHNODE_LINK_LOCAL_IPV6:8012		if (!strncmp(fnode_sess->portal_type, PORTAL_TYPE_IPV6, 4))8013			rc = sprintf(buf, "%pI6\n",8014				     fnode_conn->link_local_ipv6_addr);8015		else8016			rc = sprintf(buf, "\n");8017		break;8018	case ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX:8019		rc = sprintf(buf, "%u\n", fnode_sess->discovery_parent_idx);8020		break;8021	case ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE:8022		if (fnode_sess->discovery_parent_type == DDB_ISNS)8023			parent_type = ISCSI_DISC_PARENT_ISNS;8024		else if (fnode_sess->discovery_parent_type == DDB_NO_LINK)8025			parent_type = ISCSI_DISC_PARENT_UNKNOWN;8026		else if (fnode_sess->discovery_parent_type < MAX_DDB_ENTRIES)8027			parent_type = ISCSI_DISC_PARENT_SENDTGT;8028		else8029			parent_type = ISCSI_DISC_PARENT_UNKNOWN;8030 8031		rc = sprintf(buf, "%s\n",8032			     iscsi_get_discovery_parent_name(parent_type));8033		break;8034	case ISCSI_FLASHNODE_NAME:8035		if (fnode_sess->targetname)8036			rc = sprintf(buf, "%s\n", fnode_sess->targetname);8037		else8038			rc = sprintf(buf, "\n");8039		break;8040	case ISCSI_FLASHNODE_TPGT:8041		rc = sprintf(buf, "%u\n", fnode_sess->tpgt);8042		break;8043	case ISCSI_FLASHNODE_TCP_XMIT_WSF:8044		rc = sprintf(buf, "%u\n", fnode_conn->tcp_xmit_wsf);8045		break;8046	case ISCSI_FLASHNODE_TCP_RECV_WSF:8047		rc = sprintf(buf, "%u\n", fnode_conn->tcp_recv_wsf);8048		break;8049	case ISCSI_FLASHNODE_CHAP_OUT_IDX:8050		rc = sprintf(buf, "%u\n", fnode_sess->chap_out_idx);8051		break;8052	case ISCSI_FLASHNODE_USERNAME:8053		if (fnode_sess->chap_auth_en) {8054			qla4xxx_get_uni_chap_at_index(ha,8055						      chap_tbl.name,8056						      chap_tbl.secret,8057						      fnode_sess->chap_out_idx);8058			rc = sprintf(buf, "%s\n", chap_tbl.name);8059		} else {8060			rc = sprintf(buf, "\n");8061		}8062		break;8063	case ISCSI_FLASHNODE_PASSWORD:8064		if (fnode_sess->chap_auth_en) {8065			qla4xxx_get_uni_chap_at_index(ha,8066						      chap_tbl.name,8067						      chap_tbl.secret,8068						      fnode_sess->chap_out_idx);8069			rc = sprintf(buf, "%s\n", chap_tbl.secret);8070		} else {8071			rc = sprintf(buf, "\n");8072		}8073		break;8074	case ISCSI_FLASHNODE_STATSN:8075		rc = sprintf(buf, "%u\n", fnode_conn->statsn);8076		break;8077	case ISCSI_FLASHNODE_EXP_STATSN:8078		rc = sprintf(buf, "%u\n", fnode_conn->exp_statsn);8079		break;8080	case ISCSI_FLASHNODE_IS_BOOT_TGT:8081		rc = sprintf(buf, "%u\n", fnode_sess->is_boot_target);8082		break;8083	default:8084		rc = -ENOSYS;8085		break;8086	}8087 8088	put_device(dev);8089	return rc;8090}8091 8092/**8093 * qla4xxx_sysfs_ddb_set_param - Set parameter for firmware DDB entry8094 * @fnode_sess: pointer to session attrs of flash ddb entry8095 * @fnode_conn: pointer to connection attrs of flash ddb entry8096 * @data: Parameters and their values to update8097 * @len: len of data8098 *8099 * This sets the parameter of flash ddb entry and writes them to flash8100 **/8101static int8102qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess,8103			    struct iscsi_bus_flash_conn *fnode_conn,8104			    void *data, int len)8105{8106	struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);8107	struct scsi_qla_host *ha = to_qla_host(shost);8108	struct iscsi_flashnode_param_info *fnode_param;8109	struct ql4_chap_table chap_tbl;8110	struct nlattr *attr;8111	uint16_t chap_out_idx = INVALID_ENTRY;8112	int rc = QLA_ERROR;8113	uint32_t rem = len;8114 8115	memset((void *)&chap_tbl, 0, sizeof(chap_tbl));8116	nla_for_each_attr(attr, data, len, rem) {8117		if (nla_len(attr) < sizeof(*fnode_param)) {8118			rc = -EINVAL;8119			goto exit_set_param;8120		}8121 8122		fnode_param = nla_data(attr);8123 8124		switch (fnode_param->param) {8125		case ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6:8126			fnode_conn->is_fw_assigned_ipv6 = fnode_param->value[0];8127			break;8128		case ISCSI_FLASHNODE_PORTAL_TYPE:8129			memcpy(fnode_sess->portal_type, fnode_param->value,8130			       strlen(fnode_sess->portal_type));8131			break;8132		case ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE:8133			fnode_sess->auto_snd_tgt_disable =8134							fnode_param->value[0];8135			break;8136		case ISCSI_FLASHNODE_DISCOVERY_SESS:8137			fnode_sess->discovery_sess = fnode_param->value[0];8138			break;8139		case ISCSI_FLASHNODE_ENTRY_EN:8140			fnode_sess->entry_state = fnode_param->value[0];8141			break;8142		case ISCSI_FLASHNODE_HDR_DGST_EN:8143			fnode_conn->hdrdgst_en = fnode_param->value[0];8144			break;8145		case ISCSI_FLASHNODE_DATA_DGST_EN:8146			fnode_conn->datadgst_en = fnode_param->value[0];8147			break;8148		case ISCSI_FLASHNODE_IMM_DATA_EN:8149			fnode_sess->imm_data_en = fnode_param->value[0];8150			break;8151		case ISCSI_FLASHNODE_INITIAL_R2T_EN:8152			fnode_sess->initial_r2t_en = fnode_param->value[0];8153			break;8154		case ISCSI_FLASHNODE_DATASEQ_INORDER:8155			fnode_sess->dataseq_inorder_en = fnode_param->value[0];8156			break;8157		case ISCSI_FLASHNODE_PDU_INORDER:8158			fnode_sess->pdu_inorder_en = fnode_param->value[0];8159			break;8160		case ISCSI_FLASHNODE_CHAP_AUTH_EN:8161			fnode_sess->chap_auth_en = fnode_param->value[0];8162			/* Invalidate chap index if chap auth is disabled */8163			if (!fnode_sess->chap_auth_en)8164				fnode_sess->chap_out_idx = INVALID_ENTRY;8165 8166			break;8167		case ISCSI_FLASHNODE_SNACK_REQ_EN:8168			fnode_conn->snack_req_en = fnode_param->value[0];8169			break;8170		case ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN:8171			fnode_sess->discovery_logout_en = fnode_param->value[0];8172			break;8173		case ISCSI_FLASHNODE_BIDI_CHAP_EN:8174			fnode_sess->bidi_chap_en = fnode_param->value[0];8175			break;8176		case ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL:8177			fnode_sess->discovery_auth_optional =8178							fnode_param->value[0];8179			break;8180		case ISCSI_FLASHNODE_ERL:8181			fnode_sess->erl = fnode_param->value[0];8182			break;8183		case ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT:8184			fnode_conn->tcp_timestamp_stat = fnode_param->value[0];8185			break;8186		case ISCSI_FLASHNODE_TCP_NAGLE_DISABLE:8187			fnode_conn->tcp_nagle_disable = fnode_param->value[0];8188			break;8189		case ISCSI_FLASHNODE_TCP_WSF_DISABLE:8190			fnode_conn->tcp_wsf_disable = fnode_param->value[0];8191			break;8192		case ISCSI_FLASHNODE_TCP_TIMER_SCALE:8193			fnode_conn->tcp_timer_scale = fnode_param->value[0];8194			break;8195		case ISCSI_FLASHNODE_TCP_TIMESTAMP_EN:8196			fnode_conn->tcp_timestamp_en = fnode_param->value[0];8197			break;8198		case ISCSI_FLASHNODE_IP_FRAG_DISABLE:8199			fnode_conn->fragment_disable = fnode_param->value[0];8200			break;8201		case ISCSI_FLASHNODE_MAX_RECV_DLENGTH:8202			fnode_conn->max_recv_dlength =8203					*(unsigned *)fnode_param->value;8204			break;8205		case ISCSI_FLASHNODE_MAX_XMIT_DLENGTH:8206			fnode_conn->max_xmit_dlength =8207					*(unsigned *)fnode_param->value;8208			break;8209		case ISCSI_FLASHNODE_FIRST_BURST:8210			fnode_sess->first_burst =8211					*(unsigned *)fnode_param->value;8212			break;8213		case ISCSI_FLASHNODE_DEF_TIME2WAIT:8214			fnode_sess->time2wait = *(uint16_t *)fnode_param->value;8215			break;8216		case ISCSI_FLASHNODE_DEF_TIME2RETAIN:8217			fnode_sess->time2retain =8218						*(uint16_t *)fnode_param->value;8219			break;8220		case ISCSI_FLASHNODE_MAX_R2T:8221			fnode_sess->max_r2t =8222					*(uint16_t *)fnode_param->value;8223			break;8224		case ISCSI_FLASHNODE_KEEPALIVE_TMO:8225			fnode_conn->keepalive_timeout =8226				*(uint16_t *)fnode_param->value;8227			break;8228		case ISCSI_FLASHNODE_ISID:8229			memcpy(fnode_sess->isid, fnode_param->value,8230			       sizeof(fnode_sess->isid));8231			break;8232		case ISCSI_FLASHNODE_TSID:8233			fnode_sess->tsid = *(uint16_t *)fnode_param->value;8234			break;8235		case ISCSI_FLASHNODE_PORT:8236			fnode_conn->port = *(uint16_t *)fnode_param->value;8237			break;8238		case ISCSI_FLASHNODE_MAX_BURST:8239			fnode_sess->max_burst = *(unsigned *)fnode_param->value;8240			break;8241		case ISCSI_FLASHNODE_DEF_TASKMGMT_TMO:8242			fnode_sess->default_taskmgmt_timeout =8243						*(uint16_t *)fnode_param->value;8244			break;8245		case ISCSI_FLASHNODE_IPADDR:8246			memcpy(fnode_conn->ipaddress, fnode_param->value,8247			       IPv6_ADDR_LEN);8248			break;8249		case ISCSI_FLASHNODE_ALIAS:8250			rc = iscsi_switch_str_param(&fnode_sess->targetalias,8251						    (char *)fnode_param->value);8252			break;8253		case ISCSI_FLASHNODE_REDIRECT_IPADDR:8254			memcpy(fnode_conn->redirect_ipaddr, fnode_param->value,8255			       IPv6_ADDR_LEN);8256			break;8257		case ISCSI_FLASHNODE_MAX_SEGMENT_SIZE:8258			fnode_conn->max_segment_size =8259					*(unsigned *)fnode_param->value;8260			break;8261		case ISCSI_FLASHNODE_LOCAL_PORT:8262			fnode_conn->local_port =8263						*(uint16_t *)fnode_param->value;8264			break;8265		case ISCSI_FLASHNODE_IPV4_TOS:8266			fnode_conn->ipv4_tos = fnode_param->value[0];8267			break;8268		case ISCSI_FLASHNODE_IPV6_TC:8269			fnode_conn->ipv6_traffic_class = fnode_param->value[0];8270			break;8271		case ISCSI_FLASHNODE_IPV6_FLOW_LABEL:8272			fnode_conn->ipv6_flow_label = fnode_param->value[0];8273			break;8274		case ISCSI_FLASHNODE_NAME:8275			rc = iscsi_switch_str_param(&fnode_sess->targetname,8276						    (char *)fnode_param->value);8277			break;8278		case ISCSI_FLASHNODE_TPGT:8279			fnode_sess->tpgt = *(uint16_t *)fnode_param->value;8280			break;8281		case ISCSI_FLASHNODE_LINK_LOCAL_IPV6:8282			memcpy(fnode_conn->link_local_ipv6_addr,8283			       fnode_param->value, IPv6_ADDR_LEN);8284			break;8285		case ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX:8286			fnode_sess->discovery_parent_idx =8287						*(uint16_t *)fnode_param->value;8288			break;8289		case ISCSI_FLASHNODE_TCP_XMIT_WSF:8290			fnode_conn->tcp_xmit_wsf =8291						*(uint8_t *)fnode_param->value;8292			break;8293		case ISCSI_FLASHNODE_TCP_RECV_WSF:8294			fnode_conn->tcp_recv_wsf =8295						*(uint8_t *)fnode_param->value;8296			break;8297		case ISCSI_FLASHNODE_STATSN:8298			fnode_conn->statsn = *(uint32_t *)fnode_param->value;8299			break;8300		case ISCSI_FLASHNODE_EXP_STATSN:8301			fnode_conn->exp_statsn =8302						*(uint32_t *)fnode_param->value;8303			break;8304		case ISCSI_FLASHNODE_CHAP_OUT_IDX:8305			chap_out_idx = *(uint16_t *)fnode_param->value;8306			if (!qla4xxx_get_uni_chap_at_index(ha,8307							   chap_tbl.name,8308							   chap_tbl.secret,8309							   chap_out_idx)) {8310				fnode_sess->chap_out_idx = chap_out_idx;8311				/* Enable chap auth if chap index is valid */8312				fnode_sess->chap_auth_en = QL4_PARAM_ENABLE;8313			}8314			break;8315		default:8316			ql4_printk(KERN_ERR, ha,8317				   "%s: No such sysfs attribute\n", __func__);8318			rc = -ENOSYS;8319			goto exit_set_param;8320		}8321	}8322 8323	rc = qla4xxx_sysfs_ddb_apply(fnode_sess, fnode_conn);8324 8325exit_set_param:8326	return rc;8327}8328 8329/**8330 * qla4xxx_sysfs_ddb_delete - Delete firmware DDB entry8331 * @fnode_sess: pointer to session attrs of flash ddb entry8332 *8333 * This invalidates the flash ddb entry at the given index8334 **/8335static int qla4xxx_sysfs_ddb_delete(struct iscsi_bus_flash_session *fnode_sess)8336{8337	struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);8338	struct scsi_qla_host *ha = to_qla_host(shost);8339	uint32_t dev_db_start_offset;8340	uint32_t dev_db_end_offset;8341	struct dev_db_entry *fw_ddb_entry = NULL;8342	dma_addr_t fw_ddb_entry_dma;8343	uint16_t *ddb_cookie = NULL;8344	size_t ddb_size = 0;8345	void *pddb = NULL;8346	int target_id;8347	int rc = 0;8348 8349	if (fnode_sess->is_boot_target) {8350		rc = -EPERM;8351		DEBUG2(ql4_printk(KERN_ERR, ha,8352				  "%s: Deletion of boot target entry is not permitted.\n",8353				  __func__));8354		goto exit_ddb_del;8355	}8356 8357	if (fnode_sess->flash_state == DEV_DB_NON_PERSISTENT)8358		goto sysfs_ddb_del;8359 8360	if (is_qla40XX(ha)) {8361		dev_db_start_offset = FLASH_OFFSET_DB_INFO;8362		dev_db_end_offset = FLASH_OFFSET_DB_END;8363		dev_db_start_offset += (fnode_sess->target_id *8364				       sizeof(*fw_ddb_entry));8365		ddb_size = sizeof(*fw_ddb_entry);8366	} else {8367		dev_db_start_offset = FLASH_RAW_ACCESS_ADDR +8368				      (ha->hw.flt_region_ddb << 2);8369		/* flt_ddb_size is DDB table size for both ports8370		 * so divide it by 2 to calculate the offset for second port8371		 */8372		if (ha->port_num == 1)8373			dev_db_start_offset += (ha->hw.flt_ddb_size / 2);8374 8375		dev_db_end_offset = dev_db_start_offset +8376				    (ha->hw.flt_ddb_size / 2);8377 8378		dev_db_start_offset += (fnode_sess->target_id *8379				       sizeof(*fw_ddb_entry));8380		dev_db_start_offset += offsetof(struct dev_db_entry, cookie);8381 8382		ddb_size = sizeof(*ddb_cookie);8383	}8384 8385	DEBUG2(ql4_printk(KERN_ERR, ha, "%s: start offset=%u, end offset=%u\n",8386			  __func__, dev_db_start_offset, dev_db_end_offset));8387 8388	if (dev_db_start_offset > dev_db_end_offset) {8389		rc = -EIO;8390		DEBUG2(ql4_printk(KERN_ERR, ha, "%s:Invalid DDB index %u\n",8391				  __func__, fnode_sess->target_id));8392		goto exit_ddb_del;8393	}8394 8395	pddb = dma_alloc_coherent(&ha->pdev->dev, ddb_size,8396				  &fw_ddb_entry_dma, GFP_KERNEL);8397	if (!pddb) {8398		rc = -ENOMEM;8399		DEBUG2(ql4_printk(KERN_ERR, ha,8400				  "%s: Unable to allocate dma buffer\n",8401				  __func__));8402		goto exit_ddb_del;8403	}8404 8405	if (is_qla40XX(ha)) {8406		fw_ddb_entry = pddb;8407		memset(fw_ddb_entry, 0, ddb_size);8408		ddb_cookie = &fw_ddb_entry->cookie;8409	} else {8410		ddb_cookie = pddb;8411	}8412 8413	/* invalidate the cookie */8414	*ddb_cookie = 0xFFEE;8415	qla4xxx_set_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,8416			  ddb_size, FLASH_OPT_RMW_COMMIT);8417 8418sysfs_ddb_del:8419	target_id = fnode_sess->target_id;8420	iscsi_destroy_flashnode_sess(fnode_sess);8421	ql4_printk(KERN_INFO, ha,8422		   "%s: session and conn entries for flashnode %u of host %lu deleted\n",8423		   __func__, target_id, ha->host_no);8424exit_ddb_del:8425	if (pddb)8426		dma_free_coherent(&ha->pdev->dev, ddb_size, pddb,8427				  fw_ddb_entry_dma);8428	return rc;8429}8430 8431/**8432 * qla4xxx_sysfs_ddb_export - Create sysfs entries for firmware DDBs8433 * @ha: pointer to adapter structure8434 *8435 * Export the firmware DDB for all send targets and normal targets to sysfs.8436 **/8437int qla4xxx_sysfs_ddb_export(struct scsi_qla_host *ha)8438{8439	struct dev_db_entry *fw_ddb_entry = NULL;8440	dma_addr_t fw_ddb_entry_dma;8441	uint16_t max_ddbs;8442	uint16_t idx = 0;8443	int ret = QLA_SUCCESS;8444 8445	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,8446					  sizeof(*fw_ddb_entry),8447					  &fw_ddb_entry_dma, GFP_KERNEL);8448	if (!fw_ddb_entry) {8449		DEBUG2(ql4_printk(KERN_ERR, ha,8450				  "%s: Unable to allocate dma buffer\n",8451				  __func__));8452		return -ENOMEM;8453	}8454 8455	max_ddbs =  is_qla40XX(ha) ? MAX_PRST_DEV_DB_ENTRIES :8456				     MAX_DEV_DB_ENTRIES;8457 8458	for (idx = 0; idx < max_ddbs; idx++) {8459		if (qla4xxx_flashdb_by_index(ha, fw_ddb_entry, fw_ddb_entry_dma,8460					     idx))8461			continue;8462 8463		ret = qla4xxx_sysfs_ddb_tgt_create(ha, fw_ddb_entry, &idx, 0);8464		if (ret) {8465			ret = -EIO;8466			break;8467		}8468	}8469 8470	dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry,8471			  fw_ddb_entry_dma);8472 8473	return ret;8474}8475 8476static void qla4xxx_sysfs_ddb_remove(struct scsi_qla_host *ha)8477{8478	iscsi_destroy_all_flashnode(ha->host);8479}8480 8481/**8482 * qla4xxx_build_ddb_list - Build ddb list and setup sessions8483 * @ha: pointer to adapter structure8484 * @is_reset: Is this init path or reset path8485 *8486 * Create a list of sendtargets (st) from firmware DDBs, issue send targets8487 * using connection open, then create the list of normal targets (nt)8488 * from firmware DDBs. Based on the list of nt setup session and connection8489 * objects.8490 **/8491void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset)8492{8493	uint16_t tmo = 0;8494	struct list_head list_st, list_nt;8495	struct qla_ddb_index  *st_ddb_idx, *st_ddb_idx_tmp;8496	unsigned long wtime;8497 8498	if (!test_bit(AF_LINK_UP, &ha->flags)) {8499		set_bit(AF_BUILD_DDB_LIST, &ha->flags);8500		ha->is_reset = is_reset;8501		return;8502	}8503 8504	INIT_LIST_HEAD(&list_st);8505	INIT_LIST_HEAD(&list_nt);8506 8507	qla4xxx_build_st_list(ha, &list_st);8508 8509	/* Before issuing conn open mbox, ensure all IPs states are configured8510	 * Note, conn open fails if IPs are not configured8511	 */8512	qla4xxx_wait_for_ip_configuration(ha);8513 8514	/* Go thru the STs and fire the sendtargets by issuing conn open mbx */8515	list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) {8516		qla4xxx_conn_open(ha, st_ddb_idx->fw_ddb_idx);8517	}8518 8519	/* Wait to ensure all sendtargets are done for min 12 sec wait */8520	tmo = ((ha->def_timeout > LOGIN_TOV) &&8521	       (ha->def_timeout < LOGIN_TOV * 10) ?8522	       ha->def_timeout : LOGIN_TOV);8523 8524	DEBUG2(ql4_printk(KERN_INFO, ha,8525			  "Default time to wait for build ddb %d\n", tmo));8526 8527	wtime = jiffies + (HZ * tmo);8528	do {8529		if (list_empty(&list_st))8530			break;8531 8532		qla4xxx_remove_failed_ddb(ha, &list_st);8533		schedule_timeout_uninterruptible(HZ / 10);8534	} while (time_after(wtime, jiffies));8535 8536 8537	qla4xxx_build_nt_list(ha, &list_nt, &list_st, is_reset);8538 8539	qla4xxx_free_ddb_list(&list_st);8540	qla4xxx_free_ddb_list(&list_nt);8541 8542	qla4xxx_free_ddb_index(ha);8543}8544 8545/**8546 * qla4xxx_wait_login_resp_boot_tgt -  Wait for iSCSI boot target login8547 * response.8548 * @ha: pointer to adapter structure8549 *8550 * When the boot entry is normal iSCSI target then DF_BOOT_TGT flag will be8551 * set in DDB and we will wait for login response of boot targets during8552 * probe.8553 **/8554static void qla4xxx_wait_login_resp_boot_tgt(struct scsi_qla_host *ha)8555{8556	struct ddb_entry *ddb_entry;8557	struct dev_db_entry *fw_ddb_entry = NULL;8558	dma_addr_t fw_ddb_entry_dma;8559	unsigned long wtime;8560	uint32_t ddb_state;8561	int max_ddbs, idx, ret;8562 8563	max_ddbs =  is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :8564				     MAX_DEV_DB_ENTRIES;8565 8566	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),8567					  &fw_ddb_entry_dma, GFP_KERNEL);8568	if (!fw_ddb_entry) {8569		ql4_printk(KERN_ERR, ha,8570			   "%s: Unable to allocate dma buffer\n", __func__);8571		goto exit_login_resp;8572	}8573 8574	wtime = jiffies + (HZ * BOOT_LOGIN_RESP_TOV);8575 8576	for (idx = 0; idx < max_ddbs; idx++) {8577		ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);8578		if (ddb_entry == NULL)8579			continue;8580 8581		if (test_bit(DF_BOOT_TGT, &ddb_entry->flags)) {8582			DEBUG2(ql4_printk(KERN_INFO, ha,8583					  "%s: DDB index [%d]\n", __func__,8584					  ddb_entry->fw_ddb_index));8585			do {8586				ret = qla4xxx_get_fwddb_entry(ha,8587						ddb_entry->fw_ddb_index,8588						fw_ddb_entry, fw_ddb_entry_dma,8589						NULL, NULL, &ddb_state, NULL,8590						NULL, NULL);8591				if (ret == QLA_ERROR)8592					goto exit_login_resp;8593 8594				if ((ddb_state == DDB_DS_SESSION_ACTIVE) ||8595				    (ddb_state == DDB_DS_SESSION_FAILED))8596					break;8597 8598				schedule_timeout_uninterruptible(HZ);8599 8600			} while ((time_after(wtime, jiffies)));8601 8602			if (!time_after(wtime, jiffies)) {8603				DEBUG2(ql4_printk(KERN_INFO, ha,8604						  "%s: Login response wait timer expired\n",8605						  __func__));8606				 goto exit_login_resp;8607			}8608		}8609	}8610 8611exit_login_resp:8612	if (fw_ddb_entry)8613		dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),8614				  fw_ddb_entry, fw_ddb_entry_dma);8615}8616 8617/**8618 * qla4xxx_probe_adapter - callback function to probe HBA8619 * @pdev: pointer to pci_dev structure8620 * @ent: pointer to pci_device entry8621 *8622 * This routine will probe for Qlogic 4xxx iSCSI host adapters.8623 * It returns zero if successful. It also initializes all data necessary for8624 * the driver.8625 **/8626static int qla4xxx_probe_adapter(struct pci_dev *pdev,8627				 const struct pci_device_id *ent)8628{8629	int ret = -ENODEV, status;8630	struct Scsi_Host *host;8631	struct scsi_qla_host *ha;8632	uint8_t init_retry_count = 0;8633	char buf[34];8634	struct qla4_8xxx_legacy_intr_set *nx_legacy_intr;8635	uint32_t dev_state;8636 8637	if (pci_enable_device(pdev))8638		return -1;8639 8640	host = iscsi_host_alloc(&qla4xxx_driver_template, sizeof(*ha), 0);8641	if (host == NULL) {8642		printk(KERN_WARNING8643		       "qla4xxx: Couldn't allocate host from scsi layer!\n");8644		goto probe_disable_device;8645	}8646 8647	/* Clear our data area */8648	ha = to_qla_host(host);8649	memset(ha, 0, sizeof(*ha));8650 8651	/* Save the information from PCI BIOS.	*/8652	ha->pdev = pdev;8653	ha->host = host;8654	ha->host_no = host->host_no;8655	ha->func_num = PCI_FUNC(ha->pdev->devfn);8656 8657	/* Setup Runtime configurable options */8658	if (is_qla8022(ha)) {8659		ha->isp_ops = &qla4_82xx_isp_ops;8660		ha->reg_tbl = (uint32_t *) qla4_82xx_reg_tbl;8661		ha->qdr_sn_window = -1;8662		ha->ddr_mn_window = -1;8663		ha->curr_window = 255;8664		nx_legacy_intr = &legacy_intr[ha->func_num];8665		ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;8666		ha->nx_legacy_intr.tgt_status_reg =8667			nx_legacy_intr->tgt_status_reg;8668		ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;8669		ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;8670	} else if (is_qla8032(ha) || is_qla8042(ha)) {8671		ha->isp_ops = &qla4_83xx_isp_ops;8672		ha->reg_tbl = (uint32_t *)qla4_83xx_reg_tbl;8673	} else {8674		ha->isp_ops = &qla4xxx_isp_ops;8675	}8676 8677	if (is_qla80XX(ha)) {8678		rwlock_init(&ha->hw_lock);8679		ha->pf_bit = ha->func_num << 16;8680		/* Set EEH reset type to fundamental if required by hba */8681		pdev->needs_freset = 1;8682	}8683 8684	/* Configure PCI I/O space. */8685	ret = ha->isp_ops->iospace_config(ha);8686	if (ret)8687		goto probe_failed_ioconfig;8688 8689	ql4_printk(KERN_INFO, ha, "Found an ISP%04x, irq %d, iobase 0x%p\n",8690		   pdev->device, pdev->irq, ha->reg);8691 8692	qla4xxx_config_dma_addressing(ha);8693 8694	/* Initialize lists and spinlocks. */8695	INIT_LIST_HEAD(&ha->free_srb_q);8696 8697	mutex_init(&ha->mbox_sem);8698	mutex_init(&ha->chap_sem);8699	init_completion(&ha->mbx_intr_comp);8700	init_completion(&ha->disable_acb_comp);8701	init_completion(&ha->idc_comp);8702	init_completion(&ha->link_up_comp);8703 8704	spin_lock_init(&ha->hardware_lock);8705	spin_lock_init(&ha->work_lock);8706 8707	/* Initialize work list */8708	INIT_LIST_HEAD(&ha->work_list);8709 8710	/* Allocate dma buffers */8711	if (qla4xxx_mem_alloc(ha)) {8712		ql4_printk(KERN_WARNING, ha,8713		    "[ERROR] Failed to allocate memory for adapter\n");8714 8715		ret = -ENOMEM;8716		goto probe_failed;8717	}8718 8719	host->cmd_per_lun = 3;8720	host->max_channel = 0;8721	host->max_lun = MAX_LUNS - 1;8722	host->max_id = MAX_TARGETS;8723	host->max_cmd_len = IOCB_MAX_CDB_LEN;8724	host->can_queue = MAX_SRBS ;8725	host->transportt = qla4xxx_scsi_transport;8726 8727	pci_set_drvdata(pdev, ha);8728 8729	ret = scsi_add_host(host, &pdev->dev);8730	if (ret)8731		goto probe_failed;8732 8733	if (is_qla80XX(ha))8734		qla4_8xxx_get_flash_info(ha);8735 8736	if (is_qla8032(ha) || is_qla8042(ha)) {8737		qla4_83xx_read_reset_template(ha);8738		/*8739		 * NOTE: If ql4dontresethba==1, set IDC_CTRL DONTRESET_BIT0.8740		 * If DONRESET_BIT0 is set, drivers should not set dev_state8741		 * to NEED_RESET. But if NEED_RESET is set, drivers should8742		 * should honor the reset.8743		 */8744		if (ql4xdontresethba == 1)8745			qla4_83xx_set_idc_dontreset(ha);8746	}8747 8748	/*8749	 * Initialize the Host adapter request/response queues and8750	 * firmware8751	 * NOTE: interrupts enabled upon successful completion8752	 */8753	status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);8754 8755	/* Dont retry adapter initialization if IRQ allocation failed */8756	if (is_qla80XX(ha) && (status == QLA_ERROR))8757		goto skip_retry_init;8758 8759	while ((!test_bit(AF_ONLINE, &ha->flags)) &&8760	    init_retry_count++ < MAX_INIT_RETRIES) {8761 8762		if (is_qla80XX(ha)) {8763			ha->isp_ops->idc_lock(ha);8764			dev_state = qla4_8xxx_rd_direct(ha,8765							QLA8XXX_CRB_DEV_STATE);8766			ha->isp_ops->idc_unlock(ha);8767			if (dev_state == QLA8XXX_DEV_FAILED) {8768				ql4_printk(KERN_WARNING, ha, "%s: don't retry "8769				    "initialize adapter. H/W is in failed state\n",8770				    __func__);8771				break;8772			}8773		}8774		DEBUG2(printk("scsi: %s: retrying adapter initialization "8775			      "(%d)\n", __func__, init_retry_count));8776 8777		if (ha->isp_ops->reset_chip(ha) == QLA_ERROR)8778			continue;8779 8780		status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);8781		if (is_qla80XX(ha) && (status == QLA_ERROR)) {8782			if (qla4_8xxx_check_init_adapter_retry(ha) == QLA_ERROR)8783				goto skip_retry_init;8784		}8785	}8786 8787skip_retry_init:8788	if (!test_bit(AF_ONLINE, &ha->flags)) {8789		ql4_printk(KERN_WARNING, ha, "Failed to initialize adapter\n");8790 8791		if ((is_qla8022(ha) && ql4xdontresethba) ||8792		    ((is_qla8032(ha) || is_qla8042(ha)) &&8793		     qla4_83xx_idc_dontreset(ha))) {8794			/* Put the device in failed state. */8795			DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n"));8796			ha->isp_ops->idc_lock(ha);8797			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,8798					    QLA8XXX_DEV_FAILED);8799			ha->isp_ops->idc_unlock(ha);8800		}8801		ret = -ENODEV;8802		goto remove_host;8803	}8804 8805	/* Startup the kernel thread for this host adapter. */8806	DEBUG2(printk("scsi: %s: Starting kernel thread for "8807		      "qla4xxx_dpc\n", __func__));8808	sprintf(buf, "qla4xxx_%lu_dpc", ha->host_no);8809	ha->dpc_thread = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, buf);8810	if (!ha->dpc_thread) {8811		ql4_printk(KERN_WARNING, ha, "Unable to start DPC thread!\n");8812		ret = -ENODEV;8813		goto remove_host;8814	}8815	INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc);8816 8817	ha->task_wq = alloc_workqueue("qla4xxx_%lu_task", WQ_MEM_RECLAIM, 1,8818				      ha->host_no);8819	if (!ha->task_wq) {8820		ql4_printk(KERN_WARNING, ha, "Unable to start task thread!\n");8821		ret = -ENODEV;8822		goto remove_host;8823	}8824 8825	/*8826	 * For ISP-8XXX, request_irqs is called in qla4_8xxx_load_risc8827	 * (which is called indirectly by qla4xxx_initialize_adapter),8828	 * so that irqs will be registered after crbinit but before8829	 * mbx_intr_enable.8830	 */8831	if (is_qla40XX(ha)) {8832		ret = qla4xxx_request_irqs(ha);8833		if (ret) {8834			ql4_printk(KERN_WARNING, ha, "Failed to reserve "8835			    "interrupt %d already in use.\n", pdev->irq);8836			goto remove_host;8837		}8838	}8839 8840	pci_save_state(ha->pdev);8841	ha->isp_ops->enable_intrs(ha);8842 8843	/* Start timer thread. */8844	qla4xxx_start_timer(ha, 1);8845 8846	set_bit(AF_INIT_DONE, &ha->flags);8847 8848	qla4_8xxx_alloc_sysfs_attr(ha);8849 8850	printk(KERN_INFO8851	       " QLogic iSCSI HBA Driver version: %s\n"8852	       "  QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n",8853	       qla4xxx_version_str, ha->pdev->device, pci_name(ha->pdev),8854	       ha->host_no, ha->fw_info.fw_major, ha->fw_info.fw_minor,8855	       ha->fw_info.fw_patch, ha->fw_info.fw_build);8856 8857	/* Set the driver version */8858	if (is_qla80XX(ha))8859		qla4_8xxx_set_param(ha, SET_DRVR_VERSION);8860 8861	if (qla4xxx_setup_boot_info(ha))8862		ql4_printk(KERN_ERR, ha,8863			   "%s: No iSCSI boot target configured\n", __func__);8864 8865	set_bit(DPC_SYSFS_DDB_EXPORT, &ha->dpc_flags);8866	/* Perform the build ddb list and login to each */8867	qla4xxx_build_ddb_list(ha, INIT_ADAPTER);8868	iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb);8869	qla4xxx_wait_login_resp_boot_tgt(ha);8870 8871	qla4xxx_create_chap_list(ha);8872 8873	qla4xxx_create_ifaces(ha);8874	return 0;8875 8876remove_host:8877	scsi_remove_host(ha->host);8878 8879probe_failed:8880	qla4xxx_free_adapter(ha);8881 8882probe_failed_ioconfig:8883	scsi_host_put(ha->host);8884 8885probe_disable_device:8886	pci_disable_device(pdev);8887 8888	return ret;8889}8890 8891/**8892 * qla4xxx_prevent_other_port_reinit - prevent other port from re-initialize8893 * @ha: pointer to adapter structure8894 *8895 * Mark the other ISP-4xxx port to indicate that the driver is being removed,8896 * so that the other port will not re-initialize while in the process of8897 * removing the ha due to driver unload or hba hotplug.8898 **/8899static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha)8900{8901	struct scsi_qla_host *other_ha = NULL;8902	struct pci_dev *other_pdev = NULL;8903	int fn = ISP4XXX_PCI_FN_2;8904 8905	/*iscsi function numbers for ISP4xxx is 1 and 3*/8906	if (PCI_FUNC(ha->pdev->devfn) & BIT_1)8907		fn = ISP4XXX_PCI_FN_1;8908 8909	other_pdev =8910		pci_get_domain_bus_and_slot(pci_domain_nr(ha->pdev->bus),8911		ha->pdev->bus->number, PCI_DEVFN(PCI_SLOT(ha->pdev->devfn),8912		fn));8913 8914	/* Get other_ha if other_pdev is valid and state is enable*/8915	if (other_pdev) {8916		if (atomic_read(&other_pdev->enable_cnt)) {8917			other_ha = pci_get_drvdata(other_pdev);8918			if (other_ha) {8919				set_bit(AF_HA_REMOVAL, &other_ha->flags);8920				DEBUG2(ql4_printk(KERN_INFO, ha, "%s: "8921				    "Prevent %s reinit\n", __func__,8922				    dev_name(&other_ha->pdev->dev)));8923			}8924		}8925		pci_dev_put(other_pdev);8926	}8927}8928 8929static void qla4xxx_destroy_ddb(struct scsi_qla_host *ha,8930		struct ddb_entry *ddb_entry)8931{8932	struct dev_db_entry *fw_ddb_entry = NULL;8933	dma_addr_t fw_ddb_entry_dma;8934	unsigned long wtime;8935	uint32_t ddb_state;8936	int options;8937	int status;8938 8939	options = LOGOUT_OPTION_CLOSE_SESSION;8940	if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) == QLA_ERROR) {8941		ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", __func__);8942		goto clear_ddb;8943	}8944 8945	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),8946					  &fw_ddb_entry_dma, GFP_KERNEL);8947	if (!fw_ddb_entry) {8948		ql4_printk(KERN_ERR, ha,8949			   "%s: Unable to allocate dma buffer\n", __func__);8950		goto clear_ddb;8951	}8952 8953	wtime = jiffies + (HZ * LOGOUT_TOV);8954	do {8955		status = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index,8956						 fw_ddb_entry, fw_ddb_entry_dma,8957						 NULL, NULL, &ddb_state, NULL,8958						 NULL, NULL);8959		if (status == QLA_ERROR)8960			goto free_ddb;8961 8962		if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) ||8963		    (ddb_state == DDB_DS_SESSION_FAILED))8964			goto free_ddb;8965 8966		schedule_timeout_uninterruptible(HZ);8967	} while ((time_after(wtime, jiffies)));8968 8969free_ddb:8970	dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),8971			  fw_ddb_entry, fw_ddb_entry_dma);8972clear_ddb:8973	qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);8974}8975 8976static void qla4xxx_destroy_fw_ddb_session(struct scsi_qla_host *ha)8977{8978	struct ddb_entry *ddb_entry;8979	int idx;8980 8981	for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) {8982 8983		ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);8984		if ((ddb_entry != NULL) &&8985		    (ddb_entry->ddb_type == FLASH_DDB)) {8986 8987			qla4xxx_destroy_ddb(ha, ddb_entry);8988			/*8989			 * we have decremented the reference count of the driver8990			 * when we setup the session to have the driver unload8991			 * to be seamless without actually destroying the8992			 * session8993			 **/8994			try_module_get(qla4xxx_iscsi_transport.owner);8995			iscsi_destroy_endpoint(ddb_entry->conn->ep);8996			qla4xxx_free_ddb(ha, ddb_entry);8997			iscsi_session_teardown(ddb_entry->sess);8998		}8999	}9000}9001/**9002 * qla4xxx_remove_adapter - callback function to remove adapter.9003 * @pdev: PCI device pointer9004 **/9005static void qla4xxx_remove_adapter(struct pci_dev *pdev)9006{9007	struct scsi_qla_host *ha;9008 9009	/*9010	 * If the PCI device is disabled then it means probe_adapter had9011	 * failed and resources already cleaned up on probe_adapter exit.9012	 */9013	if (!pci_is_enabled(pdev))9014		return;9015 9016	ha = pci_get_drvdata(pdev);9017 9018	if (is_qla40XX(ha))9019		qla4xxx_prevent_other_port_reinit(ha);9020 9021	/* destroy iface from sysfs */9022	qla4xxx_destroy_ifaces(ha);9023 9024	if ((!ql4xdisablesysfsboot) && ha->boot_kset)9025		iscsi_boot_destroy_kset(ha->boot_kset);9026 9027	qla4xxx_destroy_fw_ddb_session(ha);9028	qla4_8xxx_free_sysfs_attr(ha);9029 9030	qla4xxx_sysfs_ddb_remove(ha);9031	scsi_remove_host(ha->host);9032 9033	qla4xxx_free_adapter(ha);9034 9035	scsi_host_put(ha->host);9036 9037	pci_disable_device(pdev);9038}9039 9040/**9041 * qla4xxx_config_dma_addressing() - Configure OS DMA addressing method.9042 * @ha: HA context9043 */9044static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha)9045{9046	/* Update our PCI device dma_mask for full 64 bit mask */9047	if (dma_set_mask_and_coherent(&ha->pdev->dev, DMA_BIT_MASK(64))) {9048		dev_dbg(&ha->pdev->dev,9049			  "Failed to set 64 bit PCI consistent mask; "9050			   "using 32 bit.\n");9051		dma_set_mask_and_coherent(&ha->pdev->dev, DMA_BIT_MASK(32));9052	}9053}9054 9055static int qla4xxx_slave_alloc(struct scsi_device *sdev)9056{9057	struct iscsi_cls_session *cls_sess;9058	struct iscsi_session *sess;9059	struct ddb_entry *ddb;9060	int queue_depth = QL4_DEF_QDEPTH;9061 9062	cls_sess = starget_to_session(sdev->sdev_target);9063	sess = cls_sess->dd_data;9064	ddb = sess->dd_data;9065 9066	sdev->hostdata = ddb;9067 9068	if (ql4xmaxqdepth != 0 && ql4xmaxqdepth <= 0xffffU)9069		queue_depth = ql4xmaxqdepth;9070 9071	scsi_change_queue_depth(sdev, queue_depth);9072	return 0;9073}9074 9075/**9076 * qla4xxx_del_from_active_array - returns an active srb9077 * @ha: Pointer to host adapter structure.9078 * @index: index into the active_array9079 *9080 * This routine removes and returns the srb at the specified index9081 **/9082struct srb *qla4xxx_del_from_active_array(struct scsi_qla_host *ha,9083    uint32_t index)9084{9085	struct srb *srb = NULL;9086	struct scsi_cmnd *cmd = NULL;9087 9088	cmd = scsi_host_find_tag(ha->host, index);9089	if (!cmd)9090		return srb;9091 9092	srb = qla4xxx_cmd_priv(cmd)->srb;9093	if (!srb)9094		return srb;9095 9096	/* update counters */9097	if (srb->flags & SRB_DMA_VALID) {9098		ha->iocb_cnt -= srb->iocb_cnt;9099		if (srb->cmd)9100			srb->cmd->host_scribble =9101				(unsigned char *)(unsigned long) MAX_SRBS;9102	}9103	return srb;9104}9105 9106/**9107 * qla4xxx_eh_wait_on_command - waits for command to be returned by firmware9108 * @ha: Pointer to host adapter structure.9109 * @cmd: Scsi Command to wait on.9110 *9111 * This routine waits for the command to be returned by the Firmware9112 * for some max time.9113 **/9114static int qla4xxx_eh_wait_on_command(struct scsi_qla_host *ha,9115				      struct scsi_cmnd *cmd)9116{9117	int done = 0;9118	struct srb *rp;9119	uint32_t max_wait_time = EH_WAIT_CMD_TOV;9120	int ret = SUCCESS;9121 9122	/* Dont wait on command if PCI error is being handled9123	 * by PCI AER driver9124	 */9125	if (unlikely(pci_channel_offline(ha->pdev)) ||9126	    (test_bit(AF_EEH_BUSY, &ha->flags))) {9127		ql4_printk(KERN_WARNING, ha, "scsi%ld: Return from %s\n",9128		    ha->host_no, __func__);9129		return ret;9130	}9131 9132	do {9133		/* Checking to see if its returned to OS */9134		rp = qla4xxx_cmd_priv(cmd)->srb;9135		if (rp == NULL) {9136			done++;9137			break;9138		}9139 9140		msleep(2000);9141	} while (max_wait_time--);9142 9143	return done;9144}9145 9146/**9147 * qla4xxx_wait_for_hba_online - waits for HBA to come online9148 * @ha: Pointer to host adapter structure9149 **/9150static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha)9151{9152	unsigned long wait_online;9153 9154	wait_online = jiffies + (HBA_ONLINE_TOV * HZ);9155	while (time_before(jiffies, wait_online)) {9156 9157		if (adapter_up(ha))9158			return QLA_SUCCESS;9159 9160		msleep(2000);9161	}9162 9163	return QLA_ERROR;9164}9165 9166/**9167 * qla4xxx_eh_wait_for_commands - wait for active cmds to finish.9168 * @ha: pointer to HBA9169 * @stgt: pointer to SCSI target9170 * @sdev: pointer to SCSI device9171 *9172 * This function waits for all outstanding commands to a lun to complete. It9173 * returns 0 if all pending commands are returned and 1 otherwise.9174 **/9175static int qla4xxx_eh_wait_for_commands(struct scsi_qla_host *ha,9176					struct scsi_target *stgt,9177					struct scsi_device *sdev)9178{9179	int cnt;9180	int status = 0;9181	struct scsi_cmnd *cmd;9182 9183	/*9184	 * Waiting for all commands for the designated target or dev9185	 * in the active array9186	 */9187	for (cnt = 0; cnt < ha->host->can_queue; cnt++) {9188		cmd = scsi_host_find_tag(ha->host, cnt);9189		if (cmd && stgt == scsi_target(cmd->device) &&9190		    (!sdev || sdev == cmd->device)) {9191			if (!qla4xxx_eh_wait_on_command(ha, cmd)) {9192				status++;9193				break;9194			}9195		}9196	}9197	return status;9198}9199 9200/**9201 * qla4xxx_eh_abort - callback for abort task.9202 * @cmd: Pointer to Linux's SCSI command structure9203 *9204 * This routine is called by the Linux OS to abort the specified9205 * command.9206 **/9207static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)9208{9209	struct scsi_qla_host *ha = to_qla_host(cmd->device->host);9210	unsigned int id = cmd->device->id;9211	uint64_t lun = cmd->device->lun;9212	unsigned long flags;9213	struct srb *srb = NULL;9214	int ret = SUCCESS;9215	int wait = 0;9216	int rval;9217 9218	ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Abort command issued cmd=%p, cdb=0x%x\n",9219		   ha->host_no, id, lun, cmd, cmd->cmnd[0]);9220 9221	rval = qla4xxx_isp_check_reg(ha);9222	if (rval != QLA_SUCCESS) {9223		ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");9224		return FAILED;9225	}9226 9227	spin_lock_irqsave(&ha->hardware_lock, flags);9228	srb = qla4xxx_cmd_priv(cmd)->srb;9229	if (!srb) {9230		spin_unlock_irqrestore(&ha->hardware_lock, flags);9231		ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Specified command has already completed.\n",9232			   ha->host_no, id, lun);9233		return SUCCESS;9234	}9235	kref_get(&srb->srb_ref);9236	spin_unlock_irqrestore(&ha->hardware_lock, flags);9237 9238	if (qla4xxx_abort_task(ha, srb) != QLA_SUCCESS) {9239		DEBUG3(printk("scsi%ld:%d:%llu: Abort_task mbx failed.\n",9240		    ha->host_no, id, lun));9241		ret = FAILED;9242	} else {9243		DEBUG3(printk("scsi%ld:%d:%llu: Abort_task mbx success.\n",9244		    ha->host_no, id, lun));9245		wait = 1;9246	}9247 9248	kref_put(&srb->srb_ref, qla4xxx_srb_compl);9249 9250	/* Wait for command to complete */9251	if (wait) {9252		if (!qla4xxx_eh_wait_on_command(ha, cmd)) {9253			DEBUG2(printk("scsi%ld:%d:%llu: Abort handler timed out\n",9254			    ha->host_no, id, lun));9255			ret = FAILED;9256		}9257	}9258 9259	ql4_printk(KERN_INFO, ha,9260	    "scsi%ld:%d:%llu: Abort command - %s\n",9261	    ha->host_no, id, lun, (ret == SUCCESS) ? "succeeded" : "failed");9262 9263	return ret;9264}9265 9266/**9267 * qla4xxx_eh_device_reset - callback for target reset.9268 * @cmd: Pointer to Linux's SCSI command structure9269 *9270 * This routine is called by the Linux OS to reset all luns on the9271 * specified target.9272 **/9273static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)9274{9275	struct scsi_qla_host *ha = to_qla_host(cmd->device->host);9276	struct ddb_entry *ddb_entry = cmd->device->hostdata;9277	int ret = FAILED, stat;9278	int rval;9279 9280	if (!ddb_entry)9281		return ret;9282 9283	ret = iscsi_block_scsi_eh(cmd);9284	if (ret)9285		return ret;9286	ret = FAILED;9287 9288	ql4_printk(KERN_INFO, ha,9289		   "scsi%ld:%d:%d:%llu: DEVICE RESET ISSUED.\n", ha->host_no,9290		   cmd->device->channel, cmd->device->id, cmd->device->lun);9291 9292	DEBUG2(printk(KERN_INFO9293		      "scsi%ld: DEVICE_RESET cmd=%p jiffies = 0x%lx, to=%x,"9294		      "dpc_flags=%lx, status=%x allowed=%d\n", ha->host_no,9295		      cmd, jiffies, scsi_cmd_to_rq(cmd)->timeout / HZ,9296		      ha->dpc_flags, cmd->result, cmd->allowed));9297 9298	rval = qla4xxx_isp_check_reg(ha);9299	if (rval != QLA_SUCCESS) {9300		ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");9301		return FAILED;9302	}9303 9304	/* FIXME: wait for hba to go online */9305	stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun);9306	if (stat != QLA_SUCCESS) {9307		ql4_printk(KERN_INFO, ha, "DEVICE RESET FAILED. %d\n", stat);9308		goto eh_dev_reset_done;9309	}9310 9311	if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device),9312					 cmd->device)) {9313		ql4_printk(KERN_INFO, ha,9314			   "DEVICE RESET FAILED - waiting for "9315			   "commands.\n");9316		goto eh_dev_reset_done;9317	}9318 9319	/* Send marker. */9320	if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun,9321		MM_LUN_RESET) != QLA_SUCCESS)9322		goto eh_dev_reset_done;9323 9324	ql4_printk(KERN_INFO, ha,9325		   "scsi(%ld:%d:%d:%llu): DEVICE RESET SUCCEEDED.\n",9326		   ha->host_no, cmd->device->channel, cmd->device->id,9327		   cmd->device->lun);9328 9329	ret = SUCCESS;9330 9331eh_dev_reset_done:9332 9333	return ret;9334}9335 9336/**9337 * qla4xxx_eh_target_reset - callback for target reset.9338 * @cmd: Pointer to Linux's SCSI command structure9339 *9340 * This routine is called by the Linux OS to reset the target.9341 **/9342static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)9343{9344	struct scsi_qla_host *ha = to_qla_host(cmd->device->host);9345	struct ddb_entry *ddb_entry = cmd->device->hostdata;9346	int stat, ret;9347	int rval;9348 9349	if (!ddb_entry)9350		return FAILED;9351 9352	ret = iscsi_block_scsi_eh(cmd);9353	if (ret)9354		return ret;9355 9356	starget_printk(KERN_INFO, scsi_target(cmd->device),9357		       "WARM TARGET RESET ISSUED.\n");9358 9359	DEBUG2(printk(KERN_INFO9360		      "scsi%ld: TARGET_DEVICE_RESET cmd=%p jiffies = 0x%lx, "9361		      "to=%x,dpc_flags=%lx, status=%x allowed=%d\n",9362		      ha->host_no, cmd, jiffies, scsi_cmd_to_rq(cmd)->timeout / HZ,9363		      ha->dpc_flags, cmd->result, cmd->allowed));9364 9365	rval = qla4xxx_isp_check_reg(ha);9366	if (rval != QLA_SUCCESS) {9367		ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");9368		return FAILED;9369	}9370 9371	stat = qla4xxx_reset_target(ha, ddb_entry);9372	if (stat != QLA_SUCCESS) {9373		starget_printk(KERN_INFO, scsi_target(cmd->device),9374			       "WARM TARGET RESET FAILED.\n");9375		return FAILED;9376	}9377 9378	if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device),9379					 NULL)) {9380		starget_printk(KERN_INFO, scsi_target(cmd->device),9381			       "WARM TARGET DEVICE RESET FAILED - "9382			       "waiting for commands.\n");9383		return FAILED;9384	}9385 9386	/* Send marker. */9387	if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun,9388		MM_TGT_WARM_RESET) != QLA_SUCCESS) {9389		starget_printk(KERN_INFO, scsi_target(cmd->device),9390			       "WARM TARGET DEVICE RESET FAILED - "9391			       "marker iocb failed.\n");9392		return FAILED;9393	}9394 9395	starget_printk(KERN_INFO, scsi_target(cmd->device),9396		       "WARM TARGET RESET SUCCEEDED.\n");9397	return SUCCESS;9398}9399 9400/**9401 * qla4xxx_is_eh_active - check if error handler is running9402 * @shost: Pointer to SCSI Host struct9403 *9404 * This routine finds that if reset host is called in EH9405 * scenario or from some application like sg_reset9406 **/9407static int qla4xxx_is_eh_active(struct Scsi_Host *shost)9408{9409	if (shost->shost_state == SHOST_RECOVERY)9410		return 1;9411	return 0;9412}9413 9414/**9415 * qla4xxx_eh_host_reset - kernel callback9416 * @cmd: Pointer to Linux's SCSI command structure9417 *9418 * This routine is invoked by the Linux kernel to perform fatal error9419 * recovery on the specified adapter.9420 **/9421static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)9422{9423	int return_status = FAILED;9424	struct scsi_qla_host *ha;9425	int rval;9426 9427	ha = to_qla_host(cmd->device->host);9428 9429	rval = qla4xxx_isp_check_reg(ha);9430	if (rval != QLA_SUCCESS) {9431		ql4_printk(KERN_INFO, ha, "PCI/Register disconnect, exiting.\n");9432		return FAILED;9433	}9434 9435	if ((is_qla8032(ha) || is_qla8042(ha)) && ql4xdontresethba)9436		qla4_83xx_set_idc_dontreset(ha);9437 9438	/*9439	 * For ISP8324 and ISP8042, if IDC_CTRL DONTRESET_BIT0 is set by other9440	 * protocol drivers, we should not set device_state to NEED_RESET9441	 */9442	if (ql4xdontresethba ||9443	    ((is_qla8032(ha) || is_qla8042(ha)) &&9444	     qla4_83xx_idc_dontreset(ha))) {9445		DEBUG2(printk("scsi%ld: %s: Don't Reset HBA\n",9446		     ha->host_no, __func__));9447 9448		/* Clear outstanding srb in queues */9449		if (qla4xxx_is_eh_active(cmd->device->host))9450			qla4xxx_abort_active_cmds(ha, DID_ABORT << 16);9451 9452		return FAILED;9453	}9454 9455	ql4_printk(KERN_INFO, ha,9456		   "scsi(%ld:%d:%d:%llu): HOST RESET ISSUED.\n", ha->host_no,9457		   cmd->device->channel, cmd->device->id, cmd->device->lun);9458 9459	if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) {9460		DEBUG2(printk("scsi%ld:%d: %s: Unable to reset host.  Adapter "9461			      "DEAD.\n", ha->host_no, cmd->device->channel,9462			      __func__));9463 9464		return FAILED;9465	}9466 9467	if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) {9468		if (is_qla80XX(ha))9469			set_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags);9470		else9471			set_bit(DPC_RESET_HA, &ha->dpc_flags);9472	}9473 9474	if (qla4xxx_recover_adapter(ha) == QLA_SUCCESS)9475		return_status = SUCCESS;9476 9477	ql4_printk(KERN_INFO, ha, "HOST RESET %s.\n",9478		   return_status == FAILED ? "FAILED" : "SUCCEEDED");9479 9480	return return_status;9481}9482 9483static int qla4xxx_context_reset(struct scsi_qla_host *ha)9484{9485	uint32_t mbox_cmd[MBOX_REG_COUNT];9486	uint32_t mbox_sts[MBOX_REG_COUNT];9487	struct addr_ctrl_blk_def *acb = NULL;9488	uint32_t acb_len = sizeof(struct addr_ctrl_blk_def);9489	int rval = QLA_SUCCESS;9490	dma_addr_t acb_dma;9491 9492	acb = dma_alloc_coherent(&ha->pdev->dev,9493				 sizeof(struct addr_ctrl_blk_def),9494				 &acb_dma, GFP_KERNEL);9495	if (!acb) {9496		ql4_printk(KERN_ERR, ha, "%s: Unable to alloc acb\n",9497			   __func__);9498		rval = -ENOMEM;9499		goto exit_port_reset;9500	}9501 9502	memset(acb, 0, acb_len);9503 9504	rval = qla4xxx_get_acb(ha, acb_dma, PRIMARI_ACB, acb_len);9505	if (rval != QLA_SUCCESS) {9506		rval = -EIO;9507		goto exit_free_acb;9508	}9509 9510	rval = qla4xxx_disable_acb(ha);9511	if (rval != QLA_SUCCESS) {9512		rval = -EIO;9513		goto exit_free_acb;9514	}9515 9516	wait_for_completion_timeout(&ha->disable_acb_comp,9517				    DISABLE_ACB_TOV * HZ);9518 9519	rval = qla4xxx_set_acb(ha, &mbox_cmd[0], &mbox_sts[0], acb_dma);9520	if (rval != QLA_SUCCESS) {9521		rval = -EIO;9522		goto exit_free_acb;9523	}9524 9525exit_free_acb:9526	dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk_def),9527			  acb, acb_dma);9528exit_port_reset:9529	DEBUG2(ql4_printk(KERN_INFO, ha, "%s %s\n", __func__,9530			  rval == QLA_SUCCESS ? "SUCCEEDED" : "FAILED"));9531	return rval;9532}9533 9534static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type)9535{9536	struct scsi_qla_host *ha = to_qla_host(shost);9537	int rval = QLA_SUCCESS;9538	uint32_t idc_ctrl;9539 9540	if (ql4xdontresethba) {9541		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Don't Reset HBA\n",9542				  __func__));9543		rval = -EPERM;9544		goto exit_host_reset;9545	}9546 9547	if (test_bit(DPC_RESET_HA, &ha->dpc_flags))9548		goto recover_adapter;9549 9550	switch (reset_type) {9551	case SCSI_ADAPTER_RESET:9552		set_bit(DPC_RESET_HA, &ha->dpc_flags);9553		break;9554	case SCSI_FIRMWARE_RESET:9555		if (!test_bit(DPC_RESET_HA, &ha->dpc_flags)) {9556			if (is_qla80XX(ha))9557				/* set firmware context reset */9558				set_bit(DPC_RESET_HA_FW_CONTEXT,9559					&ha->dpc_flags);9560			else {9561				rval = qla4xxx_context_reset(ha);9562				goto exit_host_reset;9563			}9564		}9565		break;9566	}9567 9568recover_adapter:9569	/* For ISP8324 and ISP8042 set graceful reset bit in IDC_DRV_CTRL if9570	 * reset is issued by application */9571	if ((is_qla8032(ha) || is_qla8042(ha)) &&9572	    test_bit(DPC_RESET_HA, &ha->dpc_flags)) {9573		idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);9574		qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL,9575				 (idc_ctrl | GRACEFUL_RESET_BIT1));9576	}9577 9578	rval = qla4xxx_recover_adapter(ha);9579	if (rval != QLA_SUCCESS) {9580		DEBUG2(ql4_printk(KERN_INFO, ha, "%s: recover adapter fail\n",9581				  __func__));9582		rval = -EIO;9583	}9584 9585exit_host_reset:9586	return rval;9587}9588 9589/* PCI AER driver recovers from all correctable errors w/o9590 * driver intervention. For uncorrectable errors PCI AER9591 * driver calls the following device driver's callbacks9592 *9593 * - Fatal Errors - link_reset9594 * - Non-Fatal Errors - driver's error_detected() which9595 * returns CAN_RECOVER, NEED_RESET or DISCONNECT.9596 *9597 * PCI AER driver calls9598 * CAN_RECOVER - driver's mmio_enabled(), mmio_enabled()9599 *               returns RECOVERED or NEED_RESET if fw_hung9600 * NEED_RESET - driver's slot_reset()9601 * DISCONNECT - device is dead & cannot recover9602 * RECOVERED - driver's resume()9603 */9604static pci_ers_result_t9605qla4xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)9606{9607	struct scsi_qla_host *ha = pci_get_drvdata(pdev);9608 9609	ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: error detected:state %x\n",9610	    ha->host_no, __func__, state);9611 9612	if (!is_aer_supported(ha))9613		return PCI_ERS_RESULT_NONE;9614 9615	switch (state) {9616	case pci_channel_io_normal:9617		clear_bit(AF_EEH_BUSY, &ha->flags);9618		return PCI_ERS_RESULT_CAN_RECOVER;9619	case pci_channel_io_frozen:9620		set_bit(AF_EEH_BUSY, &ha->flags);9621		qla4xxx_mailbox_premature_completion(ha);9622		qla4xxx_free_irqs(ha);9623		pci_disable_device(pdev);9624		/* Return back all IOs */9625		qla4xxx_abort_active_cmds(ha, DID_RESET << 16);9626		return PCI_ERS_RESULT_NEED_RESET;9627	case pci_channel_io_perm_failure:9628		set_bit(AF_EEH_BUSY, &ha->flags);9629		set_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags);9630		qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16);9631		return PCI_ERS_RESULT_DISCONNECT;9632	}9633	return PCI_ERS_RESULT_NEED_RESET;9634}9635 9636/**9637 * qla4xxx_pci_mmio_enabled() - gets called if9638 * qla4xxx_pci_error_detected() returns PCI_ERS_RESULT_CAN_RECOVER9639 * and read/write to the device still works.9640 * @pdev: PCI device pointer9641 **/9642static pci_ers_result_t9643qla4xxx_pci_mmio_enabled(struct pci_dev *pdev)9644{9645	struct scsi_qla_host *ha = pci_get_drvdata(pdev);9646 9647	if (!is_aer_supported(ha))9648		return PCI_ERS_RESULT_NONE;9649 9650	return PCI_ERS_RESULT_RECOVERED;9651}9652 9653static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)9654{9655	uint32_t rval = QLA_ERROR;9656	int fn;9657	struct pci_dev *other_pdev = NULL;9658 9659	ql4_printk(KERN_WARNING, ha, "scsi%ld: In %s\n", ha->host_no, __func__);9660 9661	set_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);9662 9663	if (test_bit(AF_ONLINE, &ha->flags)) {9664		clear_bit(AF_ONLINE, &ha->flags);9665		clear_bit(AF_LINK_UP, &ha->flags);9666		iscsi_host_for_each_session(ha->host, qla4xxx_fail_session);9667		qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);9668	}9669 9670	fn = PCI_FUNC(ha->pdev->devfn);9671	if (is_qla8022(ha)) {9672		while (fn > 0) {9673			fn--;9674			ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Finding PCI device at func %x\n",9675				   ha->host_no, __func__, fn);9676			/* Get the pci device given the domain, bus,9677			 * slot/function number */9678			other_pdev = pci_get_domain_bus_and_slot(9679					   pci_domain_nr(ha->pdev->bus),9680					   ha->pdev->bus->number,9681					   PCI_DEVFN(PCI_SLOT(ha->pdev->devfn),9682					   fn));9683 9684			if (!other_pdev)9685				continue;9686 9687			if (atomic_read(&other_pdev->enable_cnt)) {9688				ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Found PCI func in enabled state%x\n",9689					   ha->host_no, __func__, fn);9690				pci_dev_put(other_pdev);9691				break;9692			}9693			pci_dev_put(other_pdev);9694		}9695	} else {9696		/* this case is meant for ISP83xx/ISP84xx only */9697		if (qla4_83xx_can_perform_reset(ha)) {9698			/* reset fn as iSCSI is going to perform the reset */9699			fn = 0;9700		}9701	}9702 9703	/* The first function on the card, the reset owner will9704	 * start & initialize the firmware. The other functions9705	 * on the card will reset the firmware context9706	 */9707	if (!fn) {9708		ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn being reset "9709		    "0x%x is the owner\n", ha->host_no, __func__,9710		    ha->pdev->devfn);9711 9712		ha->isp_ops->idc_lock(ha);9713		qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,9714				    QLA8XXX_DEV_COLD);9715		ha->isp_ops->idc_unlock(ha);9716 9717		rval = qla4_8xxx_update_idc_reg(ha);9718		if (rval == QLA_ERROR) {9719			ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: FAILED\n",9720				   ha->host_no, __func__);9721			ha->isp_ops->idc_lock(ha);9722			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,9723					    QLA8XXX_DEV_FAILED);9724			ha->isp_ops->idc_unlock(ha);9725			goto exit_error_recovery;9726		}9727 9728		clear_bit(AF_FW_RECOVERY, &ha->flags);9729		rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);9730 9731		if (rval != QLA_SUCCESS) {9732			ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "9733			    "FAILED\n", ha->host_no, __func__);9734			qla4xxx_free_irqs(ha);9735			ha->isp_ops->idc_lock(ha);9736			qla4_8xxx_clear_drv_active(ha);9737			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,9738					    QLA8XXX_DEV_FAILED);9739			ha->isp_ops->idc_unlock(ha);9740		} else {9741			ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "9742			    "READY\n", ha->host_no, __func__);9743			ha->isp_ops->idc_lock(ha);9744			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,9745					    QLA8XXX_DEV_READY);9746			/* Clear driver state register */9747			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, 0);9748			qla4_8xxx_set_drv_active(ha);9749			ha->isp_ops->idc_unlock(ha);9750			ha->isp_ops->enable_intrs(ha);9751		}9752	} else {9753		ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn 0x%x is not "9754		    "the reset owner\n", ha->host_no, __func__,9755		    ha->pdev->devfn);9756		if ((qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE) ==9757		     QLA8XXX_DEV_READY)) {9758			clear_bit(AF_FW_RECOVERY, &ha->flags);9759			rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);9760			if (rval == QLA_SUCCESS)9761				ha->isp_ops->enable_intrs(ha);9762			else9763				qla4xxx_free_irqs(ha);9764 9765			ha->isp_ops->idc_lock(ha);9766			qla4_8xxx_set_drv_active(ha);9767			ha->isp_ops->idc_unlock(ha);9768		}9769	}9770exit_error_recovery:9771	clear_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);9772	return rval;9773}9774 9775static pci_ers_result_t9776qla4xxx_pci_slot_reset(struct pci_dev *pdev)9777{9778	pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT;9779	struct scsi_qla_host *ha = pci_get_drvdata(pdev);9780	int rc;9781 9782	ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: slot_reset\n",9783	    ha->host_no, __func__);9784 9785	if (!is_aer_supported(ha))9786		return PCI_ERS_RESULT_NONE;9787 9788	/* Restore the saved state of PCIe device -9789	 * BAR registers, PCI Config space, PCIX, MSI,9790	 * IOV states9791	 */9792	pci_restore_state(pdev);9793 9794	/* pci_restore_state() clears the saved_state flag of the device9795	 * save restored state which resets saved_state flag9796	 */9797	pci_save_state(pdev);9798 9799	/* Initialize device or resume if in suspended state */9800	rc = pci_enable_device(pdev);9801	if (rc) {9802		ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: Can't re-enable "9803		    "device after reset\n", ha->host_no, __func__);9804		goto exit_slot_reset;9805	}9806 9807	ha->isp_ops->disable_intrs(ha);9808 9809	if (is_qla80XX(ha)) {9810		if (qla4_8xxx_error_recovery(ha) == QLA_SUCCESS) {9811			ret = PCI_ERS_RESULT_RECOVERED;9812			goto exit_slot_reset;9813		} else9814			goto exit_slot_reset;9815	}9816 9817exit_slot_reset:9818	ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: Return=%x\n"9819	    "device after reset\n", ha->host_no, __func__, ret);9820	return ret;9821}9822 9823static void9824qla4xxx_pci_resume(struct pci_dev *pdev)9825{9826	struct scsi_qla_host *ha = pci_get_drvdata(pdev);9827	int ret;9828 9829	ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: pci_resume\n",9830	    ha->host_no, __func__);9831 9832	ret = qla4xxx_wait_for_hba_online(ha);9833	if (ret != QLA_SUCCESS) {9834		ql4_printk(KERN_ERR, ha, "scsi%ld: %s: the device failed to "9835		    "resume I/O from slot/link_reset\n", ha->host_no,9836		     __func__);9837	}9838 9839	clear_bit(AF_EEH_BUSY, &ha->flags);9840}9841 9842static const struct pci_error_handlers qla4xxx_err_handler = {9843	.error_detected = qla4xxx_pci_error_detected,9844	.mmio_enabled = qla4xxx_pci_mmio_enabled,9845	.slot_reset = qla4xxx_pci_slot_reset,9846	.resume = qla4xxx_pci_resume,9847};9848 9849static struct pci_device_id qla4xxx_pci_tbl[] = {9850	{9851		.vendor		= PCI_VENDOR_ID_QLOGIC,9852		.device		= PCI_DEVICE_ID_QLOGIC_ISP4010,9853		.subvendor	= PCI_ANY_ID,9854		.subdevice	= PCI_ANY_ID,9855	},9856	{9857		.vendor		= PCI_VENDOR_ID_QLOGIC,9858		.device		= PCI_DEVICE_ID_QLOGIC_ISP4022,9859		.subvendor	= PCI_ANY_ID,9860		.subdevice	= PCI_ANY_ID,9861	},9862	{9863		.vendor		= PCI_VENDOR_ID_QLOGIC,9864		.device		= PCI_DEVICE_ID_QLOGIC_ISP4032,9865		.subvendor	= PCI_ANY_ID,9866		.subdevice	= PCI_ANY_ID,9867	},9868	{9869		.vendor         = PCI_VENDOR_ID_QLOGIC,9870		.device         = PCI_DEVICE_ID_QLOGIC_ISP8022,9871		.subvendor      = PCI_ANY_ID,9872		.subdevice      = PCI_ANY_ID,9873	},9874	{9875		.vendor		= PCI_VENDOR_ID_QLOGIC,9876		.device		= PCI_DEVICE_ID_QLOGIC_ISP8324,9877		.subvendor	= PCI_ANY_ID,9878		.subdevice	= PCI_ANY_ID,9879	},9880	{9881		.vendor		= PCI_VENDOR_ID_QLOGIC,9882		.device		= PCI_DEVICE_ID_QLOGIC_ISP8042,9883		.subvendor	= PCI_ANY_ID,9884		.subdevice	= PCI_ANY_ID,9885	},9886	{0, 0},9887};9888MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl);9889 9890static struct pci_driver qla4xxx_pci_driver = {9891	.name		= DRIVER_NAME,9892	.id_table	= qla4xxx_pci_tbl,9893	.probe		= qla4xxx_probe_adapter,9894	.remove		= qla4xxx_remove_adapter,9895	.err_handler = &qla4xxx_err_handler,9896};9897 9898static int __init qla4xxx_module_init(void)9899{9900	int ret;9901 9902	if (ql4xqfulltracking)9903		qla4xxx_driver_template.track_queue_depth = 1;9904 9905	/* Allocate cache for SRBs. */9906	srb_cachep = kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0,9907				       SLAB_HWCACHE_ALIGN, NULL);9908	if (srb_cachep == NULL) {9909		printk(KERN_ERR9910		       "%s: Unable to allocate SRB cache..."9911		       "Failing load!\n", DRIVER_NAME);9912		ret = -ENOMEM;9913		goto no_srp_cache;9914	}9915 9916	/* Derive version string. */9917	strcpy(qla4xxx_version_str, QLA4XXX_DRIVER_VERSION);9918	if (ql4xextended_error_logging)9919		strcat(qla4xxx_version_str, "-debug");9920 9921	qla4xxx_scsi_transport =9922		iscsi_register_transport(&qla4xxx_iscsi_transport);9923	if (!qla4xxx_scsi_transport){9924		ret = -ENODEV;9925		goto release_srb_cache;9926	}9927 9928	ret = pci_register_driver(&qla4xxx_pci_driver);9929	if (ret)9930		goto unregister_transport;9931 9932	printk(KERN_INFO "QLogic iSCSI HBA Driver\n");9933	return 0;9934 9935unregister_transport:9936	iscsi_unregister_transport(&qla4xxx_iscsi_transport);9937release_srb_cache:9938	kmem_cache_destroy(srb_cachep);9939no_srp_cache:9940	return ret;9941}9942 9943static void __exit qla4xxx_module_exit(void)9944{9945	pci_unregister_driver(&qla4xxx_pci_driver);9946	iscsi_unregister_transport(&qla4xxx_iscsi_transport);9947	kmem_cache_destroy(srb_cachep);9948}9949 9950module_init(qla4xxx_module_init);9951module_exit(qla4xxx_module_exit);9952 9953MODULE_AUTHOR("QLogic Corporation");9954MODULE_DESCRIPTION("QLogic iSCSI HBA Driver");9955MODULE_LICENSE("GPL");9956MODULE_VERSION(QLA4XXX_DRIVER_VERSION);9957