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