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 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"); 535 else 536 len = sprintf(buf, "dhcp"); 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" : "Enabled"); 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"); 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, wrb_num; 694 unsigned short status, extd_status; 695 struct be_mcc_wrb *wrb; 696 struct be_cmd_hba_name *resp; 697 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 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 } else 706 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 707 phba->ctrl.mcc_numtag[tag]); 708 709 wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; 710 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; 711 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; 712 713 if (status || extd_status) { 714 beiscsi_log(phba, KERN_ERR, 715 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 716 "BS_%d : MailBox Command Failed with " 717 "status = %d extd_status = %d\n", 718 status, extd_status); 719 720 free_mcc_tag(&phba->ctrl, tag); 721 return -EAGAIN; 722 } 723 wrb = queue_get_wrb(mccq, wrb_num); 724 free_mcc_tag(&phba->ctrl, tag); 725 resp = embedded_payload(wrb); 726 rc = sprintf(buf, "%s\n", resp->initiator_name); 727 return rc; 728 } 729 730 /** 731 * beiscsi_get_port_state - Get the Port State 732 * @shost : pointer to scsi_host structure 733 * 734 * returns number of bytes 735 */ 736 static void beiscsi_get_port_state(struct Scsi_Host *shost) 737 { 738 struct beiscsi_hba *phba = iscsi_host_priv(shost); 739 struct iscsi_cls_host *ihost = shost->shost_data; 740 741 ihost->port_state = (phba->state == BE_ADAPTER_UP) ? 742 ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; 743 } 744 745 /** 746 * beiscsi_get_port_speed - Get the Port Speed from Adapter 747 * @shost : pointer to scsi_host structure 748 * 749 * returns Success/Failure 750 */ 751 static int beiscsi_get_port_speed(struct Scsi_Host *shost) 752 { 753 unsigned int tag, wrb_num; 754 unsigned short status, extd_status; 755 struct be_mcc_wrb *wrb; 756 struct be_cmd_ntwk_link_status_resp *resp; 757 struct beiscsi_hba *phba = iscsi_host_priv(shost); 758 struct iscsi_cls_host *ihost = shost->shost_data; 759 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 760 761 tag = be_cmd_get_port_speed(phba); 762 if (!tag) { 763 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 764 "BS_%d : Getting Port Speed Failed\n"); 765 766 return -EBUSY; 767 } else 768 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 769 phba->ctrl.mcc_numtag[tag]); 770 771 wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; 772 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; 773 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; 774 775 if (status || extd_status) { 776 beiscsi_log(phba, KERN_ERR, 777 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 778 "BS_%d : MailBox Command Failed with " 779 "status = %d extd_status = %d\n", 780 status, extd_status); 781 782 free_mcc_tag(&phba->ctrl, tag); 783 return -EAGAIN; 784 } 785 wrb = queue_get_wrb(mccq, wrb_num); 786 free_mcc_tag(&phba->ctrl, tag); 787 resp = embedded_payload(wrb); 788 789 switch (resp->mac_speed) { 790 case BE2ISCSI_LINK_SPEED_10MBPS: 791 ihost->port_speed = ISCSI_PORT_SPEED_10MBPS; 792 break; 793 case BE2ISCSI_LINK_SPEED_100MBPS: 794 ihost->port_speed = BE2ISCSI_LINK_SPEED_100MBPS; 795 break; 796 case BE2ISCSI_LINK_SPEED_1GBPS: 797 ihost->port_speed = ISCSI_PORT_SPEED_1GBPS; 798 break; 799 case BE2ISCSI_LINK_SPEED_10GBPS: 800 ihost->port_speed = ISCSI_PORT_SPEED_10GBPS; 801 break; 802 default: 803 ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN; 804 } 805 return 0; 806 } 807 808 /** 809 * beiscsi_get_host_param - get the iscsi parameter 810 * @shost: pointer to scsi_host structure 811 * @param: parameter type identifier 812 * @buf: buffer pointer 813 * 814 * returns host parameter 815 */ 816 int beiscsi_get_host_param(struct Scsi_Host *shost, 817 enum iscsi_host_param param, char *buf) 818 { 819 struct beiscsi_hba *phba = iscsi_host_priv(shost); 820 int status = 0; 821 822 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 823 "BS_%d : In beiscsi_get_host_param," 824 " param= %d\n", param); 825 826 switch (param) { 827 case ISCSI_HOST_PARAM_HWADDRESS: 828 status = beiscsi_get_macaddr(buf, phba); 829 if (status < 0) { 830 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 831 "BS_%d : beiscsi_get_macaddr Failed\n"); 832 return status; 833 } 834 break; 835 case ISCSI_HOST_PARAM_INITIATOR_NAME: 836 status = beiscsi_get_initname(buf, phba); 837 if (status < 0) { 838 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 839 "BS_%d : Retreiving Initiator Name Failed\n"); 840 return status; 841 } 842 break; 843 case ISCSI_HOST_PARAM_PORT_STATE: 844 beiscsi_get_port_state(shost); 845 status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost)); 846 break; 847 case ISCSI_HOST_PARAM_PORT_SPEED: 848 status = beiscsi_get_port_speed(shost); 849 if (status) { 850 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 851 "BS_%d : Retreiving Port Speed Failed\n"); 852 return status; 853 } 854 status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost)); 855 break; 856 default: 857 return iscsi_host_get_param(shost, param, buf); 858 } 859 return status; 860 } 861 862 int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) 863 { 864 struct be_cmd_get_nic_conf_resp resp; 865 int rc; 866 867 if (strlen(phba->mac_address)) 868 return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 869 870 memset(&resp, 0, sizeof(resp)); 871 rc = mgmt_get_nic_conf(phba, &resp); 872 if (rc) 873 return rc; 874 875 memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); 876 return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 877 } 878 879 /** 880 * beiscsi_conn_get_stats - get the iscsi stats 881 * @cls_conn: pointer to iscsi cls conn 882 * @stats: pointer to iscsi_stats structure 883 * 884 * returns iscsi stats 885 */ 886 void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, 887 struct iscsi_stats *stats) 888 { 889 struct iscsi_conn *conn = cls_conn->dd_data; 890 struct beiscsi_hba *phba = NULL; 891 892 phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 893 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 894 "BS_%d : In beiscsi_conn_get_stats\n"); 895 896 stats->txdata_octets = conn->txdata_octets; 897 stats->rxdata_octets = conn->rxdata_octets; 898 stats->dataout_pdus = conn->dataout_pdus_cnt; 899 stats->scsirsp_pdus = conn->scsirsp_pdus_cnt; 900 stats->scsicmd_pdus = conn->scsicmd_pdus_cnt; 901 stats->datain_pdus = conn->datain_pdus_cnt; 902 stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; 903 stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; 904 stats->r2t_pdus = conn->r2t_pdus_cnt; 905 stats->digest_err = 0; 906 stats->timeout_err = 0; 907 stats->custom_length = 0; 908 strcpy(stats->custom[0].desc, "eh_abort_cnt"); 909 stats->custom[0].value = conn->eh_abort_cnt; 910 } 911 912 /** 913 * beiscsi_set_params_for_offld - get the parameters for offload 914 * @beiscsi_conn: pointer to beiscsi_conn 915 * @params: pointer to offload_params structure 916 */ 917 static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn, 918 struct beiscsi_offload_params *params) 919 { 920 struct iscsi_conn *conn = beiscsi_conn->conn; 921 struct iscsi_session *session = conn->session; 922 923 AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length, 924 params, session->max_burst); 925 AMAP_SET_BITS(struct amap_beiscsi_offload_params, 926 max_send_data_segment_length, params, 927 conn->max_xmit_dlength); 928 AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length, 929 params, session->first_burst); 930 AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params, 931 session->erl); 932 AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params, 933 conn->datadgst_en); 934 AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params, 935 conn->hdrdgst_en); 936 AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params, 937 session->initial_r2t_en); 938 AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params, 939 session->imm_data_en); 940 AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params, 941 (conn->exp_statsn - 1)); 942 } 943 944 /** 945 * beiscsi_conn_start - offload of session to chip 946 * @cls_conn: pointer to beiscsi_conn 947 */ 948 int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) 949 { 950 struct iscsi_conn *conn = cls_conn->dd_data; 951 struct beiscsi_conn *beiscsi_conn = conn->dd_data; 952 struct beiscsi_endpoint *beiscsi_ep; 953 struct beiscsi_offload_params params; 954 955 beiscsi_log(beiscsi_conn->phba, KERN_INFO, 956 BEISCSI_LOG_CONFIG, 957 "BS_%d : In beiscsi_conn_start\n"); 958 959 memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); 960 beiscsi_ep = beiscsi_conn->ep; 961 if (!beiscsi_ep) 962 beiscsi_log(beiscsi_conn->phba, KERN_ERR, 963 BEISCSI_LOG_CONFIG, 964 "BS_%d : In beiscsi_conn_start , no beiscsi_ep\n"); 965 966 beiscsi_conn->login_in_progress = 0; 967 beiscsi_set_params_for_offld(beiscsi_conn, ¶ms); 968 beiscsi_offload_connection(beiscsi_conn, ¶ms); 969 iscsi_conn_start(cls_conn); 970 return 0; 971 } 972 973 /** 974 * beiscsi_get_cid - Allocate a cid 975 * @phba: The phba instance 976 */ 977 static int beiscsi_get_cid(struct beiscsi_hba *phba) 978 { 979 unsigned short cid = 0xFFFF; 980 981 if (!phba->avlbl_cids) 982 return cid; 983 984 cid = phba->cid_array[phba->cid_alloc++]; 985 if (phba->cid_alloc == phba->params.cxns_per_ctrl) 986 phba->cid_alloc = 0; 987 phba->avlbl_cids--; 988 return cid; 989 } 990 991 /** 992 * beiscsi_put_cid - Free the cid 993 * @phba: The phba for which the cid is being freed 994 * @cid: The cid to free 995 */ 996 static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) 997 { 998 phba->avlbl_cids++; 999 phba->cid_array[phba->cid_free++] = cid; 1000 if (phba->cid_free == phba->params.cxns_per_ctrl) 1001 phba->cid_free = 0; 1002 } 1003 1004 /** 1005 * beiscsi_free_ep - free endpoint 1006 * @ep: pointer to iscsi endpoint structure 1007 */ 1008 static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) 1009 { 1010 struct beiscsi_hba *phba = beiscsi_ep->phba; 1011 1012 beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 1013 beiscsi_ep->phba = NULL; 1014 } 1015 1016 /** 1017 * beiscsi_open_conn - Ask FW to open a TCP connection 1018 * @ep: endpoint to be used 1019 * @src_addr: The source IP address 1020 * @dst_addr: The Destination IP address 1021 * 1022 * Asks the FW to open a TCP connection 1023 */ 1024 static int beiscsi_open_conn(struct iscsi_endpoint *ep, 1025 struct sockaddr *src_addr, 1026 struct sockaddr *dst_addr, int non_blocking) 1027 { 1028 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 1029 struct beiscsi_hba *phba = beiscsi_ep->phba; 1030 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 1031 struct be_mcc_wrb *wrb; 1032 struct tcp_connect_and_offload_out *ptcpcnct_out; 1033 unsigned short status, extd_status; 1034 struct be_dma_mem nonemb_cmd; 1035 unsigned int tag, wrb_num; 1036 int ret = -ENOMEM; 1037 1038 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1039 "BS_%d : In beiscsi_open_conn\n"); 1040 1041 beiscsi_ep->ep_cid = beiscsi_get_cid(phba); 1042 if (beiscsi_ep->ep_cid == 0xFFFF) { 1043 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1044 "BS_%d : No free cid available\n"); 1045 return ret; 1046 } 1047 1048 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1049 "BS_%d : In beiscsi_open_conn, ep_cid=%d\n", 1050 beiscsi_ep->ep_cid); 1051 1052 phba->ep_array[beiscsi_ep->ep_cid - 1053 phba->fw_config.iscsi_cid_start] = ep; 1054 if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start + 1055 phba->params.cxns_per_ctrl * 2)) { 1056 1057 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1058 "BS_%d : Failed in allocate iscsi cid\n"); 1059 goto free_ep; 1060 } 1061 1062 beiscsi_ep->cid_vld = 0; 1063 nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, 1064 sizeof(struct tcp_connect_and_offload_in), 1065 &nonemb_cmd.dma); 1066 if (nonemb_cmd.va == NULL) { 1067 1068 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1069 "BS_%d : Failed to allocate memory for" 1070 " mgmt_open_connection\n"); 1071 1072 beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 1073 return -ENOMEM; 1074 } 1075 nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in); 1076 memset(nonemb_cmd.va, 0, nonemb_cmd.size); 1077 tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd); 1078 if (!tag) { 1079 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1080 "BS_%d : mgmt_open_connection Failed for cid=%d\n", 1081 beiscsi_ep->ep_cid); 1082 1083 beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 1084 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1085 nonemb_cmd.va, nonemb_cmd.dma); 1086 return -EAGAIN; 1087 } else { 1088 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 1089 phba->ctrl.mcc_numtag[tag]); 1090 } 1091 wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; 1092 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; 1093 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; 1094 if (status || extd_status) { 1095 beiscsi_log(phba, KERN_ERR, 1096 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 1097 "BS_%d : mgmt_open_connection Failed" 1098 " status = %d extd_status = %d\n", 1099 status, extd_status); 1100 1101 free_mcc_tag(&phba->ctrl, tag); 1102 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1103 nonemb_cmd.va, nonemb_cmd.dma); 1104 goto free_ep; 1105 } else { 1106 wrb = queue_get_wrb(mccq, wrb_num); 1107 free_mcc_tag(&phba->ctrl, tag); 1108 1109 ptcpcnct_out = embedded_payload(wrb); 1110 beiscsi_ep = ep->dd_data; 1111 beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; 1112 beiscsi_ep->cid_vld = 1; 1113 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1114 "BS_%d : mgmt_open_connection Success\n"); 1115 } 1116 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1117 nonemb_cmd.va, nonemb_cmd.dma); 1118 return 0; 1119 1120 free_ep: 1121 beiscsi_free_ep(beiscsi_ep); 1122 return -EBUSY; 1123 } 1124 1125 /** 1126 * beiscsi_ep_connect - Ask chip to create TCP Conn 1127 * @scsi_host: Pointer to scsi_host structure 1128 * @dst_addr: The IP address of Target 1129 * @non_blocking: blocking or non-blocking call 1130 * 1131 * This routines first asks chip to create a connection and then allocates an EP 1132 */ 1133 struct iscsi_endpoint * 1134 beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, 1135 int non_blocking) 1136 { 1137 struct beiscsi_hba *phba; 1138 struct beiscsi_endpoint *beiscsi_ep; 1139 struct iscsi_endpoint *ep; 1140 int ret; 1141 1142 if (shost) 1143 phba = iscsi_host_priv(shost); 1144 else { 1145 ret = -ENXIO; 1146 printk(KERN_ERR 1147 "beiscsi_ep_connect shost is NULL\n"); 1148 return ERR_PTR(ret); 1149 } 1150 1151 if (phba->state != BE_ADAPTER_UP) { 1152 ret = -EBUSY; 1153 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1154 "BS_%d : The Adapter state is Not UP\n"); 1155 return ERR_PTR(ret); 1156 } 1157 1158 ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint)); 1159 if (!ep) { 1160 ret = -ENOMEM; 1161 return ERR_PTR(ret); 1162 } 1163 1164 beiscsi_ep = ep->dd_data; 1165 beiscsi_ep->phba = phba; 1166 beiscsi_ep->openiscsi_ep = ep; 1167 ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking); 1168 if (ret) { 1169 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1170 "BS_%d : Failed in beiscsi_open_conn\n"); 1171 goto free_ep; 1172 } 1173 1174 return ep; 1175 1176 free_ep: 1177 iscsi_destroy_endpoint(ep); 1178 return ERR_PTR(ret); 1179 } 1180 1181 /** 1182 * beiscsi_ep_poll - Poll to see if connection is established 1183 * @ep: endpoint to be used 1184 * @timeout_ms: timeout specified in millisecs 1185 * 1186 * Poll to see if TCP connection established 1187 */ 1188 int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) 1189 { 1190 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 1191 1192 beiscsi_log(beiscsi_ep->phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1193 "BS_%d : In beiscsi_ep_poll\n"); 1194 1195 if (beiscsi_ep->cid_vld == 1) 1196 return 1; 1197 else 1198 return 0; 1199 } 1200 1201 /** 1202 * beiscsi_close_conn - Upload the connection 1203 * @ep: The iscsi endpoint 1204 * @flag: The type of connection closure 1205 */ 1206 static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) 1207 { 1208 int ret = 0; 1209 unsigned int tag; 1210 struct beiscsi_hba *phba = beiscsi_ep->phba; 1211 1212 tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag); 1213 if (!tag) { 1214 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1215 "BS_%d : upload failed for cid 0x%x\n", 1216 beiscsi_ep->ep_cid); 1217 1218 ret = -EAGAIN; 1219 } else { 1220 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 1221 phba->ctrl.mcc_numtag[tag]); 1222 free_mcc_tag(&phba->ctrl, tag); 1223 } 1224 return ret; 1225 } 1226 1227 /** 1228 * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table 1229 * @phba: The phba instance 1230 * @cid: The cid to free 1231 */ 1232 static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, 1233 unsigned int cid) 1234 { 1235 if (phba->conn_table[cid]) 1236 phba->conn_table[cid] = NULL; 1237 else { 1238 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1239 "BS_%d : Connection table Not occupied.\n"); 1240 return -EINVAL; 1241 } 1242 return 0; 1243 } 1244 1245 /** 1246 * beiscsi_ep_disconnect - Tears down the TCP connection 1247 * @ep: endpoint to be used 1248 * 1249 * Tears down the TCP connection 1250 */ 1251 void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) 1252 { 1253 struct beiscsi_conn *beiscsi_conn; 1254 struct beiscsi_endpoint *beiscsi_ep; 1255 struct beiscsi_hba *phba; 1256 unsigned int tag; 1257 uint8_t mgmt_invalidate_flag, tcp_upload_flag; 1258 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; 1259 1260 beiscsi_ep = ep->dd_data; 1261 phba = beiscsi_ep->phba; 1262 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1263 "BS_%d : In beiscsi_ep_disconnect for ep_cid = %d\n", 1264 beiscsi_ep->ep_cid); 1265 1266 if (beiscsi_ep->conn) { 1267 beiscsi_conn = beiscsi_ep->conn; 1268 iscsi_suspend_queue(beiscsi_conn->conn); 1269 mgmt_invalidate_flag = ~BEISCSI_NO_RST_ISSUE; 1270 tcp_upload_flag = CONNECTION_UPLOAD_GRACEFUL; 1271 } else { 1272 mgmt_invalidate_flag = BEISCSI_NO_RST_ISSUE; 1273 tcp_upload_flag = CONNECTION_UPLOAD_ABORT; 1274 } 1275 1276 tag = mgmt_invalidate_connection(phba, beiscsi_ep, 1277 beiscsi_ep->ep_cid, 1278 mgmt_invalidate_flag, 1279 savecfg_flag); 1280 if (!tag) { 1281 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1282 "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n", 1283 beiscsi_ep->ep_cid); 1284 } else { 1285 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 1286 phba->ctrl.mcc_numtag[tag]); 1287 free_mcc_tag(&phba->ctrl, tag); 1288 } 1289 1290 beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); 1291 beiscsi_free_ep(beiscsi_ep); 1292 beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); 1293 iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); 1294 } 1295 1296 umode_t be2iscsi_attr_is_visible(int param_type, int param) 1297 { 1298 switch (param_type) { 1299 case ISCSI_NET_PARAM: 1300 switch (param) { 1301 case ISCSI_NET_PARAM_IFACE_ENABLE: 1302 case ISCSI_NET_PARAM_IPV4_ADDR: 1303 case ISCSI_NET_PARAM_IPV4_SUBNET: 1304 case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 1305 case ISCSI_NET_PARAM_IPV4_GW: 1306 case ISCSI_NET_PARAM_IPV6_ADDR: 1307 case ISCSI_NET_PARAM_VLAN_ID: 1308 case ISCSI_NET_PARAM_VLAN_PRIORITY: 1309 case ISCSI_NET_PARAM_VLAN_ENABLED: 1310 return S_IRUGO; 1311 default: 1312 return 0; 1313 } 1314 case ISCSI_HOST_PARAM: 1315 switch (param) { 1316 case ISCSI_HOST_PARAM_HWADDRESS: 1317 case ISCSI_HOST_PARAM_INITIATOR_NAME: 1318 case ISCSI_HOST_PARAM_PORT_STATE: 1319 case ISCSI_HOST_PARAM_PORT_SPEED: 1320 return S_IRUGO; 1321 default: 1322 return 0; 1323 } 1324 case ISCSI_PARAM: 1325 switch (param) { 1326 case ISCSI_PARAM_MAX_RECV_DLENGTH: 1327 case ISCSI_PARAM_MAX_XMIT_DLENGTH: 1328 case ISCSI_PARAM_HDRDGST_EN: 1329 case ISCSI_PARAM_DATADGST_EN: 1330 case ISCSI_PARAM_CONN_ADDRESS: 1331 case ISCSI_PARAM_CONN_PORT: 1332 case ISCSI_PARAM_EXP_STATSN: 1333 case ISCSI_PARAM_PERSISTENT_ADDRESS: 1334 case ISCSI_PARAM_PERSISTENT_PORT: 1335 case ISCSI_PARAM_PING_TMO: 1336 case ISCSI_PARAM_RECV_TMO: 1337 case ISCSI_PARAM_INITIAL_R2T_EN: 1338 case ISCSI_PARAM_MAX_R2T: 1339 case ISCSI_PARAM_IMM_DATA_EN: 1340 case ISCSI_PARAM_FIRST_BURST: 1341 case ISCSI_PARAM_MAX_BURST: 1342 case ISCSI_PARAM_PDU_INORDER_EN: 1343 case ISCSI_PARAM_DATASEQ_INORDER_EN: 1344 case ISCSI_PARAM_ERL: 1345 case ISCSI_PARAM_TARGET_NAME: 1346 case ISCSI_PARAM_TPGT: 1347 case ISCSI_PARAM_USERNAME: 1348 case ISCSI_PARAM_PASSWORD: 1349 case ISCSI_PARAM_USERNAME_IN: 1350 case ISCSI_PARAM_PASSWORD_IN: 1351 case ISCSI_PARAM_FAST_ABORT: 1352 case ISCSI_PARAM_ABORT_TMO: 1353 case ISCSI_PARAM_LU_RESET_TMO: 1354 case ISCSI_PARAM_IFACE_NAME: 1355 case ISCSI_PARAM_INITIATOR_NAME: 1356 return S_IRUGO; 1357 default: 1358 return 0; 1359 } 1360 } 1361 1362 return 0; 1363 } 1364