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