Linux Audio

Check our new training course

Loading...
   1/**
   2 * Copyright (C) 2005 - 2011 Emulex
   3 * All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License version 2
   7 * as published by the Free Software Foundation.  The full GNU General
   8 * Public License is included in this distribution in the file called COPYING.
   9 *
  10 * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
  11 *
  12 * Contact Information:
  13 * linux-drivers@emulex.com
  14 *
  15 * Emulex
  16 * 3333 Susan Street
  17 * Costa Mesa, CA 92626
  18 */
  19
  20#include <scsi/libiscsi.h>
  21#include <scsi/scsi_transport_iscsi.h>
  22#include <scsi/scsi_transport.h>
  23#include <scsi/scsi_cmnd.h>
  24#include <scsi/scsi_device.h>
  25#include <scsi/scsi_host.h>
  26#include <scsi/scsi_netlink.h>
  27#include <net/netlink.h>
  28#include <scsi/scsi.h>
  29
  30#include "be_iscsi.h"
  31
  32extern struct iscsi_transport beiscsi_iscsi_transport;
  33
  34/**
  35 * beiscsi_session_create - creates a new iscsi session
  36 * @cmds_max: max commands supported
  37 * @qdepth: max queue depth supported
  38 * @initial_cmdsn: initial iscsi CMDSN
  39 */
  40struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
  41						 u16 cmds_max,
  42						 u16 qdepth,
  43						 u32 initial_cmdsn)
  44{
  45	struct Scsi_Host *shost;
  46	struct beiscsi_endpoint *beiscsi_ep;
  47	struct iscsi_cls_session *cls_session;
  48	struct beiscsi_hba *phba;
  49	struct iscsi_session *sess;
  50	struct beiscsi_session *beiscsi_sess;
  51	struct beiscsi_io_task *io_task;
  52
  53	SE_DEBUG(DBG_LVL_8, "In beiscsi_session_create\n");
  54
  55	if (!ep) {
  56		SE_DEBUG(DBG_LVL_1, "beiscsi_session_create: invalid ep\n");
  57		return NULL;
  58	}
  59	beiscsi_ep = ep->dd_data;
  60	phba = beiscsi_ep->phba;
  61	shost = phba->shost;
  62	if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
  63		shost_printk(KERN_ERR, shost, "Cannot handle %d cmds."
  64			     "Max cmds per session supported is %d. Using %d. "
  65			     "\n", cmds_max,
  66			      beiscsi_ep->phba->params.wrbs_per_cxn,
  67			      beiscsi_ep->phba->params.wrbs_per_cxn);
  68		cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
  69	}
  70
  71	cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
  72					  shost, cmds_max,
  73					  sizeof(*beiscsi_sess),
  74					  sizeof(*io_task),
  75					  initial_cmdsn, ISCSI_MAX_TARGET);
  76	if (!cls_session)
  77		return NULL;
  78	sess = cls_session->dd_data;
  79	beiscsi_sess = sess->dd_data;
  80	beiscsi_sess->bhs_pool =  pci_pool_create("beiscsi_bhs_pool",
  81						   phba->pcidev,
  82						   sizeof(struct be_cmd_bhs),
  83						   64, 0);
  84	if (!beiscsi_sess->bhs_pool)
  85		goto destroy_sess;
  86
  87	return cls_session;
  88destroy_sess:
  89	iscsi_session_teardown(cls_session);
  90	return NULL;
  91}
  92
  93/**
  94 * beiscsi_session_destroy - destroys iscsi session
  95 * @cls_session:	pointer to iscsi cls session
  96 *
  97 * Destroys iSCSI session instance and releases
  98 * resources allocated for it.
  99 */
 100void beiscsi_session_destroy(struct iscsi_cls_session *cls_session)
 101{
 102	struct iscsi_session *sess = cls_session->dd_data;
 103	struct beiscsi_session *beiscsi_sess = sess->dd_data;
 104
 105	SE_DEBUG(DBG_LVL_8, "In beiscsi_session_destroy\n");
 106	pci_pool_destroy(beiscsi_sess->bhs_pool);
 107	iscsi_session_teardown(cls_session);
 108}
 109
 110/**
 111 * beiscsi_conn_create - create an instance of iscsi connection
 112 * @cls_session: ptr to iscsi_cls_session
 113 * @cid: iscsi cid
 114 */
 115struct iscsi_cls_conn *
 116beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid)
 117{
 118	struct beiscsi_hba *phba;
 119	struct Scsi_Host *shost;
 120	struct iscsi_cls_conn *cls_conn;
 121	struct beiscsi_conn *beiscsi_conn;
 122	struct iscsi_conn *conn;
 123	struct iscsi_session *sess;
 124	struct beiscsi_session *beiscsi_sess;
 125
 126	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_create ,cid"
 127		 "from iscsi layer=%d\n", cid);
 128	shost = iscsi_session_to_shost(cls_session);
 129	phba = iscsi_host_priv(shost);
 130
 131	cls_conn = iscsi_conn_setup(cls_session, sizeof(*beiscsi_conn), cid);
 132	if (!cls_conn)
 133		return NULL;
 134
 135	conn = cls_conn->dd_data;
 136	beiscsi_conn = conn->dd_data;
 137	beiscsi_conn->ep = NULL;
 138	beiscsi_conn->phba = phba;
 139	beiscsi_conn->conn = conn;
 140	sess = cls_session->dd_data;
 141	beiscsi_sess = sess->dd_data;
 142	beiscsi_conn->beiscsi_sess = beiscsi_sess;
 143	return cls_conn;
 144}
 145
 146/**
 147 * beiscsi_bindconn_cid - Bind the beiscsi_conn with phba connection table
 148 * @beiscsi_conn: The pointer to  beiscsi_conn structure
 149 * @phba: The phba instance
 150 * @cid: The cid to free
 151 */
 152static int beiscsi_bindconn_cid(struct beiscsi_hba *phba,
 153				struct beiscsi_conn *beiscsi_conn,
 154				unsigned int cid)
 155{
 156	if (phba->conn_table[cid]) {
 157		SE_DEBUG(DBG_LVL_1,
 158			 "Connection table already occupied. Detected clash\n");
 159		return -EINVAL;
 160	} else {
 161		SE_DEBUG(DBG_LVL_8, "phba->conn_table[%d]=%p(beiscsi_conn)\n",
 162			 cid, beiscsi_conn);
 163		phba->conn_table[cid] = beiscsi_conn;
 164	}
 165	return 0;
 166}
 167
 168/**
 169 * beiscsi_conn_bind - Binds iscsi session/connection with TCP connection
 170 * @cls_session: pointer to iscsi cls session
 171 * @cls_conn: pointer to iscsi cls conn
 172 * @transport_fd: EP handle(64 bit)
 173 *
 174 * This function binds the TCP Conn with iSCSI Connection and Session.
 175 */
 176int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
 177		      struct iscsi_cls_conn *cls_conn,
 178		      u64 transport_fd, int is_leading)
 179{
 180	struct iscsi_conn *conn = cls_conn->dd_data;
 181	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 182	struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
 183	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 184	struct beiscsi_endpoint *beiscsi_ep;
 185	struct iscsi_endpoint *ep;
 186
 187	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_bind\n");
 188	ep = iscsi_lookup_endpoint(transport_fd);
 189	if (!ep)
 190		return -EINVAL;
 191
 192	beiscsi_ep = ep->dd_data;
 193
 194	if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
 195		return -EINVAL;
 196
 197	if (beiscsi_ep->phba != phba) {
 198		SE_DEBUG(DBG_LVL_8,
 199			 "beiscsi_ep->hba=%p not equal to phba=%p\n",
 200			 beiscsi_ep->phba, phba);
 201		return -EEXIST;
 202	}
 203
 204	beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid;
 205	beiscsi_conn->ep = beiscsi_ep;
 206	beiscsi_ep->conn = beiscsi_conn;
 207	SE_DEBUG(DBG_LVL_8, "beiscsi_conn=%p conn=%p ep_cid=%d\n",
 208		 beiscsi_conn, conn, beiscsi_ep->ep_cid);
 209	return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid);
 210}
 211
 212static int beiscsi_create_ipv4_iface(struct beiscsi_hba *phba)
 213{
 214	if (phba->ipv4_iface)
 215		return 0;
 216
 217	phba->ipv4_iface = iscsi_create_iface(phba->shost,
 218					      &beiscsi_iscsi_transport,
 219					      ISCSI_IFACE_TYPE_IPV4,
 220					      0, 0);
 221	if (!phba->ipv4_iface) {
 222		shost_printk(KERN_ERR, phba->shost, "Could not "
 223			     "create default IPv4 address.\n");
 224		return -ENODEV;
 225	}
 226
 227	return 0;
 228}
 229
 230static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba)
 231{
 232	if (phba->ipv6_iface)
 233		return 0;
 234
 235	phba->ipv6_iface = iscsi_create_iface(phba->shost,
 236					      &beiscsi_iscsi_transport,
 237					      ISCSI_IFACE_TYPE_IPV6,
 238					      0, 0);
 239	if (!phba->ipv6_iface) {
 240		shost_printk(KERN_ERR, phba->shost, "Could not "
 241			     "create default IPv6 address.\n");
 242		return -ENODEV;
 243	}
 244
 245	return 0;
 246}
 247
 248void beiscsi_create_def_ifaces(struct beiscsi_hba *phba)
 249{
 250	struct be_cmd_get_if_info_resp if_info;
 251
 252	if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info))
 253		beiscsi_create_ipv4_iface(phba);
 254
 255	if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info))
 256		beiscsi_create_ipv6_iface(phba);
 257}
 258
 259void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba)
 260{
 261	if (phba->ipv6_iface)
 262		iscsi_destroy_iface(phba->ipv6_iface);
 263	if (phba->ipv4_iface)
 264		iscsi_destroy_iface(phba->ipv4_iface);
 265}
 266
 267static int
 268beiscsi_set_static_ip(struct Scsi_Host *shost,
 269		struct iscsi_iface_param_info *iface_param,
 270		void *data, uint32_t dt_len)
 271{
 272	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 273	struct iscsi_iface_param_info *iface_ip = NULL;
 274	struct iscsi_iface_param_info *iface_subnet = NULL;
 275	struct nlattr *nla;
 276	int ret;
 277
 278
 279	switch (iface_param->param) {
 280	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
 281		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR);
 282		if (nla)
 283			iface_ip = nla_data(nla);
 284
 285		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET);
 286		if (nla)
 287			iface_subnet = nla_data(nla);
 288		break;
 289	case ISCSI_NET_PARAM_IPV4_ADDR:
 290		iface_ip = iface_param;
 291		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET);
 292		if (nla)
 293			iface_subnet = nla_data(nla);
 294		break;
 295	case ISCSI_NET_PARAM_IPV4_SUBNET:
 296		iface_subnet = iface_param;
 297		nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR);
 298		if (nla)
 299			iface_ip = nla_data(nla);
 300		break;
 301	default:
 302		shost_printk(KERN_ERR, shost, "Unsupported param %d\n",
 303			     iface_param->param);
 304	}
 305
 306	if (!iface_ip || !iface_subnet) {
 307		shost_printk(KERN_ERR, shost, "IP and Subnet Mask required\n");
 308		return -EINVAL;
 309	}
 310
 311	ret = mgmt_set_ip(phba, iface_ip, iface_subnet,
 312			ISCSI_BOOTPROTO_STATIC);
 313
 314	return ret;
 315}
 316
 317static int
 318beiscsi_set_ipv4(struct Scsi_Host *shost,
 319		struct iscsi_iface_param_info *iface_param,
 320		void *data, uint32_t dt_len)
 321{
 322	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 323	int ret = 0;
 324
 325	/* Check the param */
 326	switch (iface_param->param) {
 327	case ISCSI_NET_PARAM_IPV4_GW:
 328		ret = mgmt_set_gateway(phba, iface_param);
 329		break;
 330	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
 331		if (iface_param->value[0] == ISCSI_BOOTPROTO_DHCP)
 332			ret = mgmt_set_ip(phba, iface_param,
 333					NULL, ISCSI_BOOTPROTO_DHCP);
 334		else if (iface_param->value[0] == ISCSI_BOOTPROTO_STATIC)
 335			ret = beiscsi_set_static_ip(shost, iface_param,
 336						    data, dt_len);
 337		else
 338			shost_printk(KERN_ERR, shost, "Invalid BOOTPROTO: %d\n",
 339					iface_param->value[0]);
 340		break;
 341	case ISCSI_NET_PARAM_IFACE_ENABLE:
 342		if (iface_param->value[0] == ISCSI_IFACE_ENABLE)
 343			ret = beiscsi_create_ipv4_iface(phba);
 344		else
 345			iscsi_destroy_iface(phba->ipv4_iface);
 346		break;
 347	case ISCSI_NET_PARAM_IPV4_SUBNET:
 348	case ISCSI_NET_PARAM_IPV4_ADDR:
 349		ret = beiscsi_set_static_ip(shost, iface_param,
 350					    data, dt_len);
 351		break;
 352	default:
 353		shost_printk(KERN_ERR, shost, "Param %d not supported\n",
 354			     iface_param->param);
 355	}
 356
 357	return ret;
 358}
 359
 360static int
 361beiscsi_set_ipv6(struct Scsi_Host *shost,
 362		struct iscsi_iface_param_info *iface_param,
 363		void *data, uint32_t dt_len)
 364{
 365	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 366	int ret = 0;
 367
 368	switch (iface_param->param) {
 369	case ISCSI_NET_PARAM_IFACE_ENABLE:
 370		if (iface_param->value[0] == ISCSI_IFACE_ENABLE)
 371			ret = beiscsi_create_ipv6_iface(phba);
 372		else {
 373			iscsi_destroy_iface(phba->ipv6_iface);
 374			ret = 0;
 375		}
 376		break;
 377	case ISCSI_NET_PARAM_IPV6_ADDR:
 378		ret = mgmt_set_ip(phba, iface_param, NULL,
 379				  ISCSI_BOOTPROTO_STATIC);
 380		break;
 381	default:
 382		shost_printk(KERN_ERR, shost, "Param %d not supported\n",
 383			     iface_param->param);
 384	}
 385
 386	return ret;
 387}
 388
 389int be2iscsi_iface_set_param(struct Scsi_Host *shost,
 390		void *data, uint32_t dt_len)
 391{
 392	struct iscsi_iface_param_info *iface_param = NULL;
 393	struct nlattr *attrib;
 394	uint32_t rm_len = dt_len;
 395	int ret = 0 ;
 396
 397	nla_for_each_attr(attrib, data, dt_len, rm_len) {
 398		iface_param = nla_data(attrib);
 399
 400		if (iface_param->param_type != ISCSI_NET_PARAM)
 401			continue;
 402
 403		/*
 404		 * BE2ISCSI only supports 1 interface
 405		 */
 406		if (iface_param->iface_num) {
 407			shost_printk(KERN_ERR, shost, "Invalid iface_num %d."
 408				     "Only iface_num 0 is supported.\n",
 409				     iface_param->iface_num);
 410			return -EINVAL;
 411		}
 412
 413		switch (iface_param->iface_type) {
 414		case ISCSI_IFACE_TYPE_IPV4:
 415			ret = beiscsi_set_ipv4(shost, iface_param,
 416					       data, dt_len);
 417			break;
 418		case ISCSI_IFACE_TYPE_IPV6:
 419			ret = beiscsi_set_ipv6(shost, iface_param,
 420					       data, dt_len);
 421			break;
 422		default:
 423			shost_printk(KERN_ERR, shost,
 424				     "Invalid iface type :%d passed\n",
 425				     iface_param->iface_type);
 426			break;
 427		}
 428
 429		if (ret)
 430			return ret;
 431	}
 432
 433	return ret;
 434}
 435
 436static int be2iscsi_get_if_param(struct beiscsi_hba *phba,
 437		struct iscsi_iface *iface, int param,
 438		char *buf)
 439{
 440	struct be_cmd_get_if_info_resp if_info;
 441	int len, ip_type = BE2_IPV4;
 442
 443	memset(&if_info, 0, sizeof(if_info));
 444
 445	if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
 446		ip_type = BE2_IPV6;
 447
 448	len = mgmt_get_if_info(phba, ip_type, &if_info);
 449	if (len)
 450		return len;
 451
 452	switch (param) {
 453	case ISCSI_NET_PARAM_IPV4_ADDR:
 454		len = sprintf(buf, "%pI4\n", &if_info.ip_addr.addr);
 455		break;
 456	case ISCSI_NET_PARAM_IPV6_ADDR:
 457		len = sprintf(buf, "%pI6\n", &if_info.ip_addr.addr);
 458		break;
 459	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
 460		if (!if_info.dhcp_state)
 461			len = sprintf(buf, "static");
 462		else
 463			len = sprintf(buf, "dhcp");
 464		break;
 465	case ISCSI_NET_PARAM_IPV4_SUBNET:
 466		len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask);
 467		break;
 468	default:
 469		WARN_ON(1);
 470	}
 471
 472	return len;
 473}
 474
 475int be2iscsi_iface_get_param(struct iscsi_iface *iface,
 476		enum iscsi_param_type param_type,
 477		int param, char *buf)
 478{
 479	struct Scsi_Host *shost = iscsi_iface_to_shost(iface);
 480	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 481	struct be_cmd_get_def_gateway_resp gateway;
 482	int len = -ENOSYS;
 483
 484	switch (param) {
 485	case ISCSI_NET_PARAM_IPV4_ADDR:
 486	case ISCSI_NET_PARAM_IPV4_SUBNET:
 487	case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
 488	case ISCSI_NET_PARAM_IPV6_ADDR:
 489		len = be2iscsi_get_if_param(phba, iface, param, buf);
 490		break;
 491	case ISCSI_NET_PARAM_IFACE_ENABLE:
 492		len = sprintf(buf, "enabled");
 493		break;
 494	case ISCSI_NET_PARAM_IPV4_GW:
 495		memset(&gateway, 0, sizeof(gateway));
 496		len = mgmt_get_gateway(phba, BE2_IPV4, &gateway);
 497		if (!len)
 498			len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr);
 499		break;
 500	default:
 501		len = -ENOSYS;
 502	}
 503
 504	return len;
 505}
 506
 507/**
 508 * beiscsi_ep_get_param - get the iscsi parameter
 509 * @ep: pointer to iscsi ep
 510 * @param: parameter type identifier
 511 * @buf: buffer pointer
 512 *
 513 * returns iscsi parameter
 514 */
 515int beiscsi_ep_get_param(struct iscsi_endpoint *ep,
 516			   enum iscsi_param param, char *buf)
 517{
 518	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
 519	int len = 0;
 520
 521	SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_get_param, param= %d\n", param);
 522
 523	switch (param) {
 524	case ISCSI_PARAM_CONN_PORT:
 525		len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport);
 526		break;
 527	case ISCSI_PARAM_CONN_ADDRESS:
 528		if (beiscsi_ep->ip_type == BE2_IPV4)
 529			len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr);
 530		else
 531			len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr);
 532		break;
 533	default:
 534		return -ENOSYS;
 535	}
 536	return len;
 537}
 538
 539int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
 540		      enum iscsi_param param, char *buf, int buflen)
 541{
 542	struct iscsi_conn *conn = cls_conn->dd_data;
 543	struct iscsi_session *session = conn->session;
 544	int ret;
 545
 546	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_set_param, param= %d\n", param);
 547	ret = iscsi_set_param(cls_conn, param, buf, buflen);
 548	if (ret)
 549		return ret;
 550	/*
 551	 * If userspace tried to set the value to higher than we can
 552	 * support override here.
 553	 */
 554	switch (param) {
 555	case ISCSI_PARAM_FIRST_BURST:
 556		if (session->first_burst > 8192)
 557			session->first_burst = 8192;
 558		break;
 559	case ISCSI_PARAM_MAX_RECV_DLENGTH:
 560		if (conn->max_recv_dlength > 65536)
 561			conn->max_recv_dlength = 65536;
 562		break;
 563	case ISCSI_PARAM_MAX_BURST:
 564		if (session->max_burst > 262144)
 565			session->max_burst = 262144;
 566		break;
 567	case ISCSI_PARAM_MAX_XMIT_DLENGTH:
 568		if ((conn->max_xmit_dlength > 65536) ||
 569		    (conn->max_xmit_dlength == 0))
 570			conn->max_xmit_dlength = 65536;
 571	default:
 572		return 0;
 573	}
 574
 575	return 0;
 576}
 577
 578/**
 579 * beiscsi_get_initname - Read Initiator Name from flash
 580 * @buf: buffer bointer
 581 * @phba: The device priv structure instance
 582 *
 583 * returns number of bytes
 584 */
 585static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba)
 586{
 587	int rc;
 588	unsigned int tag, wrb_num;
 589	unsigned short status, extd_status;
 590	struct be_mcc_wrb *wrb;
 591	struct be_cmd_hba_name *resp;
 592	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
 593
 594	tag = be_cmd_get_initname(phba);
 595	if (!tag) {
 596		SE_DEBUG(DBG_LVL_1, "Getting Initiator Name Failed\n");
 597		return -EBUSY;
 598	} else
 599		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
 600				phba->ctrl.mcc_numtag[tag]);
 601
 602	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
 603	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
 604	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
 605
 606	if (status || extd_status) {
 607		SE_DEBUG(DBG_LVL_1, "MailBox Command Failed with "
 608				"status = %d extd_status = %d\n",
 609				status, extd_status);
 610		free_mcc_tag(&phba->ctrl, tag);
 611		return -EAGAIN;
 612	}
 613	wrb = queue_get_wrb(mccq, wrb_num);
 614	free_mcc_tag(&phba->ctrl, tag);
 615	resp = embedded_payload(wrb);
 616	rc = sprintf(buf, "%s\n", resp->initiator_name);
 617	return rc;
 618}
 619
 620/**
 621 * beiscsi_get_port_state - Get the Port State
 622 * @shost : pointer to scsi_host structure
 623 *
 624 * returns number of bytes
 625 */
 626static void beiscsi_get_port_state(struct Scsi_Host *shost)
 627{
 628	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 629	struct iscsi_cls_host *ihost = shost->shost_data;
 630
 631	ihost->port_state = (phba->state == BE_ADAPTER_UP) ?
 632		ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN;
 633}
 634
 635/**
 636 * beiscsi_get_port_speed  - Get the Port Speed from Adapter
 637 * @shost : pointer to scsi_host structure
 638 *
 639 * returns Success/Failure
 640 */
 641static int beiscsi_get_port_speed(struct Scsi_Host *shost)
 642{
 643	unsigned int tag, wrb_num;
 644	unsigned short status, extd_status;
 645	struct be_mcc_wrb *wrb;
 646	struct be_cmd_ntwk_link_status_resp *resp;
 647	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 648	struct iscsi_cls_host *ihost = shost->shost_data;
 649	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
 650
 651	tag = be_cmd_get_port_speed(phba);
 652	if (!tag) {
 653		SE_DEBUG(DBG_LVL_1, "Getting Port Speed Failed\n");
 654		 return -EBUSY;
 655	 } else
 656		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
 657				phba->ctrl.mcc_numtag[tag]);
 658
 659	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
 660	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
 661	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
 662
 663	if (status || extd_status) {
 664		SE_DEBUG(DBG_LVL_1, "MailBox Command Failed with "
 665				"status = %d extd_status = %d\n",
 666				status, extd_status);
 667		free_mcc_tag(&phba->ctrl, tag);
 668		return -EAGAIN;
 669	}
 670	wrb = queue_get_wrb(mccq, wrb_num);
 671	free_mcc_tag(&phba->ctrl, tag);
 672	resp = embedded_payload(wrb);
 673
 674	switch (resp->mac_speed) {
 675	case BE2ISCSI_LINK_SPEED_10MBPS:
 676		ihost->port_speed = ISCSI_PORT_SPEED_10MBPS;
 677		break;
 678	case BE2ISCSI_LINK_SPEED_100MBPS:
 679		ihost->port_speed = BE2ISCSI_LINK_SPEED_100MBPS;
 680		break;
 681	case BE2ISCSI_LINK_SPEED_1GBPS:
 682		ihost->port_speed = ISCSI_PORT_SPEED_1GBPS;
 683		break;
 684	case BE2ISCSI_LINK_SPEED_10GBPS:
 685		ihost->port_speed = ISCSI_PORT_SPEED_10GBPS;
 686		break;
 687	default:
 688		ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN;
 689	}
 690	return 0;
 691}
 692
 693/**
 694 * beiscsi_get_host_param - get the iscsi parameter
 695 * @shost: pointer to scsi_host structure
 696 * @param: parameter type identifier
 697 * @buf: buffer pointer
 698 *
 699 * returns host parameter
 700 */
 701int beiscsi_get_host_param(struct Scsi_Host *shost,
 702			   enum iscsi_host_param param, char *buf)
 703{
 704	struct beiscsi_hba *phba = iscsi_host_priv(shost);
 705	int status = 0;
 706
 707	SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param);
 708	switch (param) {
 709	case ISCSI_HOST_PARAM_HWADDRESS:
 710		status = beiscsi_get_macaddr(buf, phba);
 711		if (status < 0) {
 712			SE_DEBUG(DBG_LVL_1, "beiscsi_get_macaddr Failed\n");
 713			return status;
 714		}
 715		break;
 716	case ISCSI_HOST_PARAM_INITIATOR_NAME:
 717		status = beiscsi_get_initname(buf, phba);
 718		if (status < 0) {
 719			SE_DEBUG(DBG_LVL_1,
 720					"Retreiving Initiator Name Failed\n");
 721			return status;
 722		}
 723		break;
 724	case ISCSI_HOST_PARAM_PORT_STATE:
 725		beiscsi_get_port_state(shost);
 726		status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost));
 727		break;
 728	case ISCSI_HOST_PARAM_PORT_SPEED:
 729		status = beiscsi_get_port_speed(shost);
 730		if (status) {
 731			SE_DEBUG(DBG_LVL_1,
 732					"Retreiving Port Speed Failed\n");
 733			return status;
 734		}
 735		status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost));
 736		break;
 737	default:
 738		return iscsi_host_get_param(shost, param, buf);
 739	}
 740	return status;
 741}
 742
 743int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
 744{
 745	struct be_cmd_get_nic_conf_resp resp;
 746	int rc;
 747
 748	if (strlen(phba->mac_address))
 749		return strlcpy(buf, phba->mac_address, PAGE_SIZE);
 750
 751	memset(&resp, 0, sizeof(resp));
 752	rc = mgmt_get_nic_conf(phba, &resp);
 753	if (rc)
 754		return rc;
 755
 756	memcpy(phba->mac_address, resp.mac_address, ETH_ALEN);
 757	return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
 758}
 759
 760/**
 761 * beiscsi_conn_get_stats - get the iscsi stats
 762 * @cls_conn: pointer to iscsi cls conn
 763 * @stats: pointer to iscsi_stats structure
 764 *
 765 * returns iscsi stats
 766 */
 767void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn,
 768			    struct iscsi_stats *stats)
 769{
 770	struct iscsi_conn *conn = cls_conn->dd_data;
 771
 772	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_stats\n");
 773	stats->txdata_octets = conn->txdata_octets;
 774	stats->rxdata_octets = conn->rxdata_octets;
 775	stats->dataout_pdus = conn->dataout_pdus_cnt;
 776	stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
 777	stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
 778	stats->datain_pdus = conn->datain_pdus_cnt;
 779	stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
 780	stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
 781	stats->r2t_pdus = conn->r2t_pdus_cnt;
 782	stats->digest_err = 0;
 783	stats->timeout_err = 0;
 784	stats->custom_length = 0;
 785	strcpy(stats->custom[0].desc, "eh_abort_cnt");
 786	stats->custom[0].value = conn->eh_abort_cnt;
 787}
 788
 789/**
 790 * beiscsi_set_params_for_offld - get the parameters for offload
 791 * @beiscsi_conn: pointer to beiscsi_conn
 792 * @params: pointer to offload_params structure
 793 */
 794static void  beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn,
 795					  struct beiscsi_offload_params *params)
 796{
 797	struct iscsi_conn *conn = beiscsi_conn->conn;
 798	struct iscsi_session *session = conn->session;
 799
 800	AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length,
 801		      params, session->max_burst);
 802	AMAP_SET_BITS(struct amap_beiscsi_offload_params,
 803		      max_send_data_segment_length, params,
 804		      conn->max_xmit_dlength);
 805	AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length,
 806		      params, session->first_burst);
 807	AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params,
 808		      session->erl);
 809	AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params,
 810		      conn->datadgst_en);
 811	AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params,
 812		      conn->hdrdgst_en);
 813	AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params,
 814		      session->initial_r2t_en);
 815	AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params,
 816		      session->imm_data_en);
 817	AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params,
 818		      (conn->exp_statsn - 1));
 819}
 820
 821/**
 822 * beiscsi_conn_start - offload of session to chip
 823 * @cls_conn: pointer to beiscsi_conn
 824 */
 825int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
 826{
 827	struct iscsi_conn *conn = cls_conn->dd_data;
 828	struct beiscsi_conn *beiscsi_conn = conn->dd_data;
 829	struct beiscsi_endpoint *beiscsi_ep;
 830	struct beiscsi_offload_params params;
 831
 832	SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_start\n");
 833	memset(&params, 0, sizeof(struct beiscsi_offload_params));
 834	beiscsi_ep = beiscsi_conn->ep;
 835	if (!beiscsi_ep)
 836		SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n");
 837
 838	beiscsi_conn->login_in_progress = 0;
 839	beiscsi_set_params_for_offld(beiscsi_conn, &params);
 840	beiscsi_offload_connection(beiscsi_conn, &params);
 841	iscsi_conn_start(cls_conn);
 842	return 0;
 843}
 844
 845/**
 846 * beiscsi_get_cid - Allocate a cid
 847 * @phba: The phba instance
 848 */
 849static int beiscsi_get_cid(struct beiscsi_hba *phba)
 850{
 851	unsigned short cid = 0xFFFF;
 852
 853	if (!phba->avlbl_cids)
 854		return cid;
 855
 856	cid = phba->cid_array[phba->cid_alloc++];
 857	if (phba->cid_alloc == phba->params.cxns_per_ctrl)
 858		phba->cid_alloc = 0;
 859	phba->avlbl_cids--;
 860	return cid;
 861}
 862
 863/**
 864 * beiscsi_put_cid - Free the cid
 865 * @phba: The phba for which the cid is being freed
 866 * @cid: The cid to free
 867 */
 868static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
 869{
 870	phba->avlbl_cids++;
 871	phba->cid_array[phba->cid_free++] = cid;
 872	if (phba->cid_free == phba->params.cxns_per_ctrl)
 873		phba->cid_free = 0;
 874}
 875
 876/**
 877 * beiscsi_free_ep - free endpoint
 878 * @ep:	pointer to iscsi endpoint structure
 879 */
 880static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
 881{
 882	struct beiscsi_hba *phba = beiscsi_ep->phba;
 883
 884	beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
 885	beiscsi_ep->phba = NULL;
 886}
 887
 888/**
 889 * beiscsi_open_conn - Ask FW to open a TCP connection
 890 * @ep:	endpoint to be used
 891 * @src_addr: The source IP address
 892 * @dst_addr: The Destination  IP address
 893 *
 894 * Asks the FW to open a TCP connection
 895 */
 896static int beiscsi_open_conn(struct iscsi_endpoint *ep,
 897			     struct sockaddr *src_addr,
 898			     struct sockaddr *dst_addr, int non_blocking)
 899{
 900	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
 901	struct beiscsi_hba *phba = beiscsi_ep->phba;
 902	struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
 903	struct be_mcc_wrb *wrb;
 904	struct tcp_connect_and_offload_out *ptcpcnct_out;
 905	unsigned short status, extd_status;
 906	struct be_dma_mem nonemb_cmd;
 907	unsigned int tag, wrb_num;
 908	int ret = -ENOMEM;
 909
 910	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn\n");
 911	beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
 912	if (beiscsi_ep->ep_cid == 0xFFFF) {
 913		SE_DEBUG(DBG_LVL_1, "No free cid available\n");
 914		return ret;
 915	}
 916	SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d\n",
 917		 beiscsi_ep->ep_cid);
 918	phba->ep_array[beiscsi_ep->ep_cid -
 919		       phba->fw_config.iscsi_cid_start] = ep;
 920	if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
 921				  phba->params.cxns_per_ctrl * 2)) {
 922		SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
 923		goto free_ep;
 924	}
 925
 926	beiscsi_ep->cid_vld = 0;
 927	nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
 928				sizeof(struct tcp_connect_and_offload_in),
 929				&nonemb_cmd.dma);
 930	if (nonemb_cmd.va == NULL) {
 931		SE_DEBUG(DBG_LVL_1,
 932			 "Failed to allocate memory for mgmt_open_connection"
 933			 "\n");
 934		beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
 935		return -ENOMEM;
 936	}
 937	nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in);
 938	memset(nonemb_cmd.va, 0, nonemb_cmd.size);
 939	tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
 940	if (!tag) {
 941		SE_DEBUG(DBG_LVL_1,
 942			 "mgmt_open_connection Failed for cid=%d\n",
 943			 beiscsi_ep->ep_cid);
 944		beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
 945		pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
 946				    nonemb_cmd.va, nonemb_cmd.dma);
 947		return -EAGAIN;
 948	} else {
 949		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
 950					 phba->ctrl.mcc_numtag[tag]);
 951	}
 952	wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16;
 953	extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
 954	status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
 955	if (status || extd_status) {
 956		SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed"
 957				    " status = %d extd_status = %d\n",
 958				    status, extd_status);
 959		free_mcc_tag(&phba->ctrl, tag);
 960		pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
 961			    nonemb_cmd.va, nonemb_cmd.dma);
 962		goto free_ep;
 963	} else {
 964		wrb = queue_get_wrb(mccq, wrb_num);
 965		free_mcc_tag(&phba->ctrl, tag);
 966
 967		ptcpcnct_out = embedded_payload(wrb);
 968		beiscsi_ep = ep->dd_data;
 969		beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
 970		beiscsi_ep->cid_vld = 1;
 971		SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
 972	}
 973	pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
 974			    nonemb_cmd.va, nonemb_cmd.dma);
 975	return 0;
 976
 977free_ep:
 978	beiscsi_free_ep(beiscsi_ep);
 979	return -EBUSY;
 980}
 981
 982/**
 983 * beiscsi_ep_connect - Ask chip to create TCP Conn
 984 * @scsi_host: Pointer to scsi_host structure
 985 * @dst_addr: The IP address of Target
 986 * @non_blocking: blocking or non-blocking call
 987 *
 988 * This routines first asks chip to create a connection and then allocates an EP
 989 */
 990struct iscsi_endpoint *
 991beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
 992		   int non_blocking)
 993{
 994	struct beiscsi_hba *phba;
 995	struct beiscsi_endpoint *beiscsi_ep;
 996	struct iscsi_endpoint *ep;
 997	int ret;
 998
 999	SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_connect\n");
1000	if (shost)
1001		phba = iscsi_host_priv(shost);
1002	else {
1003		ret = -ENXIO;
1004		SE_DEBUG(DBG_LVL_1, "shost is NULL\n");
1005		return ERR_PTR(ret);
1006	}
1007
1008	if (phba->state != BE_ADAPTER_UP) {
1009		ret = -EBUSY;
1010		SE_DEBUG(DBG_LVL_1, "The Adapter state is Not UP\n");
1011		return ERR_PTR(ret);
1012	}
1013
1014	ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
1015	if (!ep) {
1016		ret = -ENOMEM;
1017		return ERR_PTR(ret);
1018	}
1019
1020	beiscsi_ep = ep->dd_data;
1021	beiscsi_ep->phba = phba;
1022	beiscsi_ep->openiscsi_ep = ep;
1023	ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking);
1024	if (ret) {
1025		SE_DEBUG(DBG_LVL_1, "Failed in beiscsi_open_conn\n");
1026		goto free_ep;
1027	}
1028
1029	return ep;
1030
1031free_ep:
1032	iscsi_destroy_endpoint(ep);
1033	return ERR_PTR(ret);
1034}
1035
1036/**
1037 * beiscsi_ep_poll - Poll to see if connection is established
1038 * @ep:	endpoint to be used
1039 * @timeout_ms: timeout specified in millisecs
1040 *
1041 * Poll to see if TCP connection established
1042 */
1043int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
1044{
1045	struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
1046
1047	SE_DEBUG(DBG_LVL_8, "In  beiscsi_ep_poll\n");
1048	if (beiscsi_ep->cid_vld == 1)
1049		return 1;
1050	else
1051		return 0;
1052}
1053
1054/**
1055 * beiscsi_close_conn - Upload the  connection
1056 * @ep: The iscsi endpoint
1057 * @flag: The type of connection closure
1058 */
1059static int beiscsi_close_conn(struct  beiscsi_endpoint *beiscsi_ep, int flag)
1060{
1061	int ret = 0;
1062	unsigned int tag;
1063	struct beiscsi_hba *phba = beiscsi_ep->phba;
1064
1065	tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag);
1066	if (!tag) {
1067		SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x\n",
1068			 beiscsi_ep->ep_cid);
1069		ret = -EAGAIN;
1070	} else {
1071		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
1072					 phba->ctrl.mcc_numtag[tag]);
1073		free_mcc_tag(&phba->ctrl, tag);
1074	}
1075	return ret;
1076}
1077
1078/**
1079 * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table
1080 * @phba: The phba instance
1081 * @cid: The cid to free
1082 */
1083static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba,
1084				      unsigned int cid)
1085{
1086	if (phba->conn_table[cid])
1087		phba->conn_table[cid] = NULL;
1088	else {
1089		SE_DEBUG(DBG_LVL_8, "Connection table Not occupied.\n");
1090		return -EINVAL;
1091	}
1092	return 0;
1093}
1094
1095/**
1096 * beiscsi_ep_disconnect - Tears down the TCP connection
1097 * @ep:	endpoint to be used
1098 *
1099 * Tears down the TCP connection
1100 */
1101void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
1102{
1103	struct beiscsi_conn *beiscsi_conn;
1104	struct beiscsi_endpoint *beiscsi_ep;
1105	struct beiscsi_hba *phba;
1106	unsigned int tag;
1107	unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
1108
1109	beiscsi_ep = ep->dd_data;
1110	phba = beiscsi_ep->phba;
1111	SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect for ep_cid = %d\n",
1112			     beiscsi_ep->ep_cid);
1113
1114	if (!beiscsi_ep->conn) {
1115		SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect, no "
1116			 "beiscsi_ep\n");
1117		return;
1118	}
1119	beiscsi_conn = beiscsi_ep->conn;
1120	iscsi_suspend_queue(beiscsi_conn->conn);
1121
1122	SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect ep_cid = %d\n",
1123		 beiscsi_ep->ep_cid);
1124
1125	tag = mgmt_invalidate_connection(phba, beiscsi_ep,
1126					    beiscsi_ep->ep_cid, 1,
1127					    savecfg_flag);
1128	if (!tag) {
1129		SE_DEBUG(DBG_LVL_1,
1130			 "mgmt_invalidate_connection Failed for cid=%d\n",
1131			  beiscsi_ep->ep_cid);
1132	} else {
1133		wait_event_interruptible(phba->ctrl.mcc_wait[tag],
1134					 phba->ctrl.mcc_numtag[tag]);
1135		free_mcc_tag(&phba->ctrl, tag);
1136	}
1137
1138	beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL);
1139	beiscsi_free_ep(beiscsi_ep);
1140	beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
1141	iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep);
1142}
1143
1144umode_t be2iscsi_attr_is_visible(int param_type, int param)
1145{
1146	switch (param_type) {
1147	case ISCSI_NET_PARAM:
1148		switch (param) {
1149		case ISCSI_NET_PARAM_IFACE_ENABLE:
1150		case ISCSI_NET_PARAM_IPV4_ADDR:
1151		case ISCSI_NET_PARAM_IPV4_SUBNET:
1152		case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
1153		case ISCSI_NET_PARAM_IPV4_GW:
1154		case ISCSI_NET_PARAM_IPV6_ADDR:
1155			return S_IRUGO;
1156		default:
1157			return 0;
1158		}
1159	case ISCSI_HOST_PARAM:
1160		switch (param) {
1161		case ISCSI_HOST_PARAM_HWADDRESS:
1162		case ISCSI_HOST_PARAM_INITIATOR_NAME:
1163		case ISCSI_HOST_PARAM_PORT_STATE:
1164		case ISCSI_HOST_PARAM_PORT_SPEED:
1165			return S_IRUGO;
1166		default:
1167			return 0;
1168		}
1169	case ISCSI_PARAM:
1170		switch (param) {
1171		case ISCSI_PARAM_MAX_RECV_DLENGTH:
1172		case ISCSI_PARAM_MAX_XMIT_DLENGTH:
1173		case ISCSI_PARAM_HDRDGST_EN:
1174		case ISCSI_PARAM_DATADGST_EN:
1175		case ISCSI_PARAM_CONN_ADDRESS:
1176		case ISCSI_PARAM_CONN_PORT:
1177		case ISCSI_PARAM_EXP_STATSN:
1178		case ISCSI_PARAM_PERSISTENT_ADDRESS:
1179		case ISCSI_PARAM_PERSISTENT_PORT:
1180		case ISCSI_PARAM_PING_TMO:
1181		case ISCSI_PARAM_RECV_TMO:
1182		case ISCSI_PARAM_INITIAL_R2T_EN:
1183		case ISCSI_PARAM_MAX_R2T:
1184		case ISCSI_PARAM_IMM_DATA_EN:
1185		case ISCSI_PARAM_FIRST_BURST:
1186		case ISCSI_PARAM_MAX_BURST:
1187		case ISCSI_PARAM_PDU_INORDER_EN:
1188		case ISCSI_PARAM_DATASEQ_INORDER_EN:
1189		case ISCSI_PARAM_ERL:
1190		case ISCSI_PARAM_TARGET_NAME:
1191		case ISCSI_PARAM_TPGT:
1192		case ISCSI_PARAM_USERNAME:
1193		case ISCSI_PARAM_PASSWORD:
1194		case ISCSI_PARAM_USERNAME_IN:
1195		case ISCSI_PARAM_PASSWORD_IN:
1196		case ISCSI_PARAM_FAST_ABORT:
1197		case ISCSI_PARAM_ABORT_TMO:
1198		case ISCSI_PARAM_LU_RESET_TMO:
1199		case ISCSI_PARAM_IFACE_NAME:
1200		case ISCSI_PARAM_INITIATOR_NAME:
1201			return S_IRUGO;
1202		default:
1203			return 0;
1204		}
1205	}
1206
1207	return 0;
1208}