diff options
| -rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 1002 | ||||
| -rw-r--r-- | include/scsi/iscsi_if.h | 113 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 151 |
3 files changed, 1265 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 0a74b975efdf..ce06e8772f3a 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/bsg-lib.h> | 26 | #include <linux/bsg-lib.h> |
| 27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
| 28 | #include <linux/list.h> | ||
| 28 | #include <net/tcp.h> | 29 | #include <net/tcp.h> |
| 29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
| 30 | #include <scsi/scsi_host.h> | 31 | #include <scsi/scsi_host.h> |
| @@ -460,6 +461,689 @@ void iscsi_destroy_iface(struct iscsi_iface *iface) | |||
| 460 | EXPORT_SYMBOL_GPL(iscsi_destroy_iface); | 461 | EXPORT_SYMBOL_GPL(iscsi_destroy_iface); |
| 461 | 462 | ||
| 462 | /* | 463 | /* |
| 464 | * Interface to display flash node params to sysfs | ||
| 465 | */ | ||
| 466 | |||
| 467 | #define ISCSI_FLASHNODE_ATTR(_prefix, _name, _mode, _show, _store) \ | ||
| 468 | struct device_attribute dev_attr_##_prefix##_##_name = \ | ||
| 469 | __ATTR(_name, _mode, _show, _store) | ||
| 470 | |||
| 471 | /* flash node session attrs show */ | ||
| 472 | #define iscsi_flashnode_sess_attr_show(type, name, param) \ | ||
| 473 | static ssize_t \ | ||
| 474 | show_##type##_##name(struct device *dev, struct device_attribute *attr, \ | ||
| 475 | char *buf) \ | ||
| 476 | { \ | ||
| 477 | struct iscsi_bus_flash_session *fnode_sess = \ | ||
| 478 | iscsi_dev_to_flash_session(dev);\ | ||
| 479 | struct iscsi_transport *t = fnode_sess->transport; \ | ||
| 480 | return t->get_flashnode_param(fnode_sess, param, buf); \ | ||
| 481 | } \ | ||
| 482 | |||
| 483 | |||
| 484 | #define iscsi_flashnode_sess_attr(type, name, param) \ | ||
| 485 | iscsi_flashnode_sess_attr_show(type, name, param) \ | ||
| 486 | static ISCSI_FLASHNODE_ATTR(type, name, S_IRUGO, \ | ||
| 487 | show_##type##_##name, NULL); | ||
| 488 | |||
| 489 | /* Flash node session attributes */ | ||
| 490 | |||
| 491 | iscsi_flashnode_sess_attr(fnode, auto_snd_tgt_disable, | ||
| 492 | ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE); | ||
| 493 | iscsi_flashnode_sess_attr(fnode, discovery_session, | ||
| 494 | ISCSI_FLASHNODE_DISCOVERY_SESS); | ||
| 495 | iscsi_flashnode_sess_attr(fnode, portal_type, ISCSI_FLASHNODE_PORTAL_TYPE); | ||
| 496 | iscsi_flashnode_sess_attr(fnode, entry_enable, ISCSI_FLASHNODE_ENTRY_EN); | ||
| 497 | iscsi_flashnode_sess_attr(fnode, immediate_data, ISCSI_FLASHNODE_IMM_DATA_EN); | ||
| 498 | iscsi_flashnode_sess_attr(fnode, initial_r2t, ISCSI_FLASHNODE_INITIAL_R2T_EN); | ||
| 499 | iscsi_flashnode_sess_attr(fnode, data_seq_in_order, | ||
| 500 | ISCSI_FLASHNODE_DATASEQ_INORDER); | ||
| 501 | iscsi_flashnode_sess_attr(fnode, data_pdu_in_order, | ||
| 502 | ISCSI_FLASHNODE_PDU_INORDER); | ||
| 503 | iscsi_flashnode_sess_attr(fnode, chap_auth, ISCSI_FLASHNODE_CHAP_AUTH_EN); | ||
| 504 | iscsi_flashnode_sess_attr(fnode, discovery_logout, | ||
| 505 | ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN); | ||
| 506 | iscsi_flashnode_sess_attr(fnode, bidi_chap, ISCSI_FLASHNODE_BIDI_CHAP_EN); | ||
| 507 | iscsi_flashnode_sess_attr(fnode, discovery_auth_optional, | ||
| 508 | ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL); | ||
| 509 | iscsi_flashnode_sess_attr(fnode, erl, ISCSI_FLASHNODE_ERL); | ||
| 510 | iscsi_flashnode_sess_attr(fnode, first_burst_len, ISCSI_FLASHNODE_FIRST_BURST); | ||
| 511 | iscsi_flashnode_sess_attr(fnode, def_time2wait, ISCSI_FLASHNODE_DEF_TIME2WAIT); | ||
| 512 | iscsi_flashnode_sess_attr(fnode, def_time2retain, | ||
| 513 | ISCSI_FLASHNODE_DEF_TIME2RETAIN); | ||
| 514 | iscsi_flashnode_sess_attr(fnode, max_outstanding_r2t, ISCSI_FLASHNODE_MAX_R2T); | ||
| 515 | iscsi_flashnode_sess_attr(fnode, isid, ISCSI_FLASHNODE_ISID); | ||
| 516 | iscsi_flashnode_sess_attr(fnode, tsid, ISCSI_FLASHNODE_TSID); | ||
| 517 | iscsi_flashnode_sess_attr(fnode, max_burst_len, ISCSI_FLASHNODE_MAX_BURST); | ||
| 518 | iscsi_flashnode_sess_attr(fnode, def_taskmgmt_tmo, | ||
| 519 | ISCSI_FLASHNODE_DEF_TASKMGMT_TMO); | ||
| 520 | iscsi_flashnode_sess_attr(fnode, targetalias, ISCSI_FLASHNODE_ALIAS); | ||
| 521 | iscsi_flashnode_sess_attr(fnode, targetname, ISCSI_FLASHNODE_NAME); | ||
| 522 | iscsi_flashnode_sess_attr(fnode, tpgt, ISCSI_FLASHNODE_TPGT); | ||
| 523 | iscsi_flashnode_sess_attr(fnode, discovery_parent_idx, | ||
| 524 | ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX); | ||
| 525 | iscsi_flashnode_sess_attr(fnode, discovery_parent_type, | ||
| 526 | ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE); | ||
| 527 | iscsi_flashnode_sess_attr(fnode, chap_in_idx, ISCSI_FLASHNODE_CHAP_IN_IDX); | ||
| 528 | iscsi_flashnode_sess_attr(fnode, chap_out_idx, ISCSI_FLASHNODE_CHAP_OUT_IDX); | ||
| 529 | iscsi_flashnode_sess_attr(fnode, username, ISCSI_FLASHNODE_USERNAME); | ||
| 530 | iscsi_flashnode_sess_attr(fnode, username_in, ISCSI_FLASHNODE_USERNAME_IN); | ||
| 531 | iscsi_flashnode_sess_attr(fnode, password, ISCSI_FLASHNODE_PASSWORD); | ||
| 532 | iscsi_flashnode_sess_attr(fnode, password_in, ISCSI_FLASHNODE_PASSWORD_IN); | ||
| 533 | iscsi_flashnode_sess_attr(fnode, is_boot_target, ISCSI_FLASHNODE_IS_BOOT_TGT); | ||
| 534 | |||
| 535 | static struct attribute *iscsi_flashnode_sess_attrs[] = { | ||
| 536 | &dev_attr_fnode_auto_snd_tgt_disable.attr, | ||
| 537 | &dev_attr_fnode_discovery_session.attr, | ||
| 538 | &dev_attr_fnode_portal_type.attr, | ||
| 539 | &dev_attr_fnode_entry_enable.attr, | ||
| 540 | &dev_attr_fnode_immediate_data.attr, | ||
| 541 | &dev_attr_fnode_initial_r2t.attr, | ||
| 542 | &dev_attr_fnode_data_seq_in_order.attr, | ||
| 543 | &dev_attr_fnode_data_pdu_in_order.attr, | ||
| 544 | &dev_attr_fnode_chap_auth.attr, | ||
| 545 | &dev_attr_fnode_discovery_logout.attr, | ||
| 546 | &dev_attr_fnode_bidi_chap.attr, | ||
| 547 | &dev_attr_fnode_discovery_auth_optional.attr, | ||
| 548 | &dev_attr_fnode_erl.attr, | ||
| 549 | &dev_attr_fnode_first_burst_len.attr, | ||
| 550 | &dev_attr_fnode_def_time2wait.attr, | ||
| 551 | &dev_attr_fnode_def_time2retain.attr, | ||
| 552 | &dev_attr_fnode_max_outstanding_r2t.attr, | ||
| 553 | &dev_attr_fnode_isid.attr, | ||
| 554 | &dev_attr_fnode_tsid.attr, | ||
| 555 | &dev_attr_fnode_max_burst_len.attr, | ||
| 556 | &dev_attr_fnode_def_taskmgmt_tmo.attr, | ||
| 557 | &dev_attr_fnode_targetalias.attr, | ||
| 558 | &dev_attr_fnode_targetname.attr, | ||
| 559 | &dev_attr_fnode_tpgt.attr, | ||
| 560 | &dev_attr_fnode_discovery_parent_idx.attr, | ||
| 561 | &dev_attr_fnode_discovery_parent_type.attr, | ||
| 562 | &dev_attr_fnode_chap_in_idx.attr, | ||
| 563 | &dev_attr_fnode_chap_out_idx.attr, | ||
| 564 | &dev_attr_fnode_username.attr, | ||
| 565 | &dev_attr_fnode_username_in.attr, | ||
| 566 | &dev_attr_fnode_password.attr, | ||
| 567 | &dev_attr_fnode_password_in.attr, | ||
| 568 | &dev_attr_fnode_is_boot_target.attr, | ||
| 569 | NULL, | ||
| 570 | }; | ||
| 571 | |||
| 572 | static umode_t iscsi_flashnode_sess_attr_is_visible(struct kobject *kobj, | ||
| 573 | struct attribute *attr, | ||
| 574 | int i) | ||
| 575 | { | ||
| 576 | struct device *dev = container_of(kobj, struct device, kobj); | ||
| 577 | struct iscsi_bus_flash_session *fnode_sess = | ||
| 578 | iscsi_dev_to_flash_session(dev); | ||
| 579 | struct iscsi_transport *t = fnode_sess->transport; | ||
| 580 | int param; | ||
| 581 | |||
| 582 | if (attr == &dev_attr_fnode_auto_snd_tgt_disable.attr) { | ||
| 583 | param = ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE; | ||
| 584 | } else if (attr == &dev_attr_fnode_discovery_session.attr) { | ||
| 585 | param = ISCSI_FLASHNODE_DISCOVERY_SESS; | ||
| 586 | } else if (attr == &dev_attr_fnode_portal_type.attr) { | ||
| 587 | param = ISCSI_FLASHNODE_PORTAL_TYPE; | ||
| 588 | } else if (attr == &dev_attr_fnode_entry_enable.attr) { | ||
| 589 | param = ISCSI_FLASHNODE_ENTRY_EN; | ||
| 590 | } else if (attr == &dev_attr_fnode_immediate_data.attr) { | ||
| 591 | param = ISCSI_FLASHNODE_IMM_DATA_EN; | ||
| 592 | } else if (attr == &dev_attr_fnode_initial_r2t.attr) { | ||
| 593 | param = ISCSI_FLASHNODE_INITIAL_R2T_EN; | ||
| 594 | } else if (attr == &dev_attr_fnode_data_seq_in_order.attr) { | ||
| 595 | param = ISCSI_FLASHNODE_DATASEQ_INORDER; | ||
| 596 | } else if (attr == &dev_attr_fnode_data_pdu_in_order.attr) { | ||
| 597 | param = ISCSI_FLASHNODE_PDU_INORDER; | ||
| 598 | } else if (attr == &dev_attr_fnode_chap_auth.attr) { | ||
| 599 | param = ISCSI_FLASHNODE_CHAP_AUTH_EN; | ||
| 600 | } else if (attr == &dev_attr_fnode_discovery_logout.attr) { | ||
| 601 | param = ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN; | ||
| 602 | } else if (attr == &dev_attr_fnode_bidi_chap.attr) { | ||
| 603 | param = ISCSI_FLASHNODE_BIDI_CHAP_EN; | ||
| 604 | } else if (attr == &dev_attr_fnode_discovery_auth_optional.attr) { | ||
| 605 | param = ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL; | ||
| 606 | } else if (attr == &dev_attr_fnode_erl.attr) { | ||
| 607 | param = ISCSI_FLASHNODE_ERL; | ||
| 608 | } else if (attr == &dev_attr_fnode_first_burst_len.attr) { | ||
| 609 | param = ISCSI_FLASHNODE_FIRST_BURST; | ||
| 610 | } else if (attr == &dev_attr_fnode_def_time2wait.attr) { | ||
| 611 | param = ISCSI_FLASHNODE_DEF_TIME2WAIT; | ||
| 612 | } else if (attr == &dev_attr_fnode_def_time2retain.attr) { | ||
| 613 | param = ISCSI_FLASHNODE_DEF_TIME2RETAIN; | ||
| 614 | } else if (attr == &dev_attr_fnode_max_outstanding_r2t.attr) { | ||
| 615 | param = ISCSI_FLASHNODE_MAX_R2T; | ||
| 616 | } else if (attr == &dev_attr_fnode_isid.attr) { | ||
| 617 | param = ISCSI_FLASHNODE_ISID; | ||
| 618 | } else if (attr == &dev_attr_fnode_tsid.attr) { | ||
| 619 | param = ISCSI_FLASHNODE_TSID; | ||
| 620 | } else if (attr == &dev_attr_fnode_max_burst_len.attr) { | ||
| 621 | param = ISCSI_FLASHNODE_MAX_BURST; | ||
| 622 | } else if (attr == &dev_attr_fnode_def_taskmgmt_tmo.attr) { | ||
| 623 | param = ISCSI_FLASHNODE_DEF_TASKMGMT_TMO; | ||
| 624 | } else if (attr == &dev_attr_fnode_targetalias.attr) { | ||
| 625 | param = ISCSI_FLASHNODE_ALIAS; | ||
| 626 | } else if (attr == &dev_attr_fnode_targetname.attr) { | ||
| 627 | param = ISCSI_FLASHNODE_NAME; | ||
| 628 | } else if (attr == &dev_attr_fnode_tpgt.attr) { | ||
| 629 | param = ISCSI_FLASHNODE_TPGT; | ||
| 630 | } else if (attr == &dev_attr_fnode_discovery_parent_idx.attr) { | ||
| 631 | param = ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX; | ||
| 632 | } else if (attr == &dev_attr_fnode_discovery_parent_type.attr) { | ||
| 633 | param = ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE; | ||
| 634 | } else if (attr == &dev_attr_fnode_chap_in_idx.attr) { | ||
| 635 | param = ISCSI_FLASHNODE_CHAP_IN_IDX; | ||
| 636 | } else if (attr == &dev_attr_fnode_chap_out_idx.attr) { | ||
| 637 | param = ISCSI_FLASHNODE_CHAP_OUT_IDX; | ||
| 638 | } else if (attr == &dev_attr_fnode_username.attr) { | ||
| 639 | param = ISCSI_FLASHNODE_USERNAME; | ||
| 640 | } else if (attr == &dev_attr_fnode_username_in.attr) { | ||
| 641 | param = ISCSI_FLASHNODE_USERNAME_IN; | ||
| 642 | } else if (attr == &dev_attr_fnode_password.attr) { | ||
| 643 | param = ISCSI_FLASHNODE_PASSWORD; | ||
| 644 | } else if (attr == &dev_attr_fnode_password_in.attr) { | ||
| 645 | param = ISCSI_FLASHNODE_PASSWORD_IN; | ||
| 646 | } else if (attr == &dev_attr_fnode_is_boot_target.attr) { | ||
| 647 | param = ISCSI_FLASHNODE_IS_BOOT_TGT; | ||
| 648 | } else { | ||
| 649 | WARN_ONCE(1, "Invalid flashnode session attr"); | ||
| 650 | return 0; | ||
| 651 | } | ||
| 652 | |||
| 653 | return t->attr_is_visible(ISCSI_FLASHNODE_PARAM, param); | ||
| 654 | } | ||
| 655 | |||
| 656 | static struct attribute_group iscsi_flashnode_sess_attr_group = { | ||
| 657 | .attrs = iscsi_flashnode_sess_attrs, | ||
| 658 | .is_visible = iscsi_flashnode_sess_attr_is_visible, | ||
| 659 | }; | ||
| 660 | |||
| 661 | static const struct attribute_group *iscsi_flashnode_sess_attr_groups[] = { | ||
| 662 | &iscsi_flashnode_sess_attr_group, | ||
| 663 | NULL, | ||
| 664 | }; | ||
| 665 | |||
| 666 | static void iscsi_flashnode_sess_release(struct device *dev) | ||
| 667 | { | ||
| 668 | struct iscsi_bus_flash_session *fnode_sess = | ||
| 669 | iscsi_dev_to_flash_session(dev); | ||
| 670 | |||
| 671 | kfree(fnode_sess->targetname); | ||
| 672 | kfree(fnode_sess->targetalias); | ||
| 673 | kfree(fnode_sess->portal_type); | ||
| 674 | kfree(fnode_sess); | ||
| 675 | } | ||
| 676 | |||
| 677 | struct device_type iscsi_flashnode_sess_dev_type = { | ||
| 678 | .name = "iscsi_flashnode_sess_dev_type", | ||
| 679 | .groups = iscsi_flashnode_sess_attr_groups, | ||
| 680 | .release = iscsi_flashnode_sess_release, | ||
| 681 | }; | ||
| 682 | |||
| 683 | /* flash node connection attrs show */ | ||
| 684 | #define iscsi_flashnode_conn_attr_show(type, name, param) \ | ||
| 685 | static ssize_t \ | ||
| 686 | show_##type##_##name(struct device *dev, struct device_attribute *attr, \ | ||
| 687 | char *buf) \ | ||
| 688 | { \ | ||
| 689 | struct iscsi_bus_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev);\ | ||
| 690 | struct iscsi_bus_flash_session *fnode_sess = \ | ||
| 691 | iscsi_flash_conn_to_flash_session(fnode_conn);\ | ||
| 692 | struct iscsi_transport *t = fnode_conn->transport; \ | ||
| 693 | return t->get_flashnode_param(fnode_sess, param, buf); \ | ||
| 694 | } \ | ||
| 695 | |||
| 696 | |||
| 697 | #define iscsi_flashnode_conn_attr(type, name, param) \ | ||
| 698 | iscsi_flashnode_conn_attr_show(type, name, param) \ | ||
| 699 | static ISCSI_FLASHNODE_ATTR(type, name, S_IRUGO, \ | ||
| 700 | show_##type##_##name, NULL); | ||
| 701 | |||
| 702 | /* Flash node connection attributes */ | ||
| 703 | |||
| 704 | iscsi_flashnode_conn_attr(fnode, is_fw_assigned_ipv6, | ||
| 705 | ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6); | ||
| 706 | iscsi_flashnode_conn_attr(fnode, header_digest, ISCSI_FLASHNODE_HDR_DGST_EN); | ||
| 707 | iscsi_flashnode_conn_attr(fnode, data_digest, ISCSI_FLASHNODE_DATA_DGST_EN); | ||
| 708 | iscsi_flashnode_conn_attr(fnode, snack_req, ISCSI_FLASHNODE_SNACK_REQ_EN); | ||
| 709 | iscsi_flashnode_conn_attr(fnode, tcp_timestamp_stat, | ||
| 710 | ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT); | ||
| 711 | iscsi_flashnode_conn_attr(fnode, tcp_nagle_disable, | ||
| 712 | ISCSI_FLASHNODE_TCP_NAGLE_DISABLE); | ||
| 713 | iscsi_flashnode_conn_attr(fnode, tcp_wsf_disable, | ||
| 714 | ISCSI_FLASHNODE_TCP_WSF_DISABLE); | ||
| 715 | iscsi_flashnode_conn_attr(fnode, tcp_timer_scale, | ||
| 716 | ISCSI_FLASHNODE_TCP_TIMER_SCALE); | ||
| 717 | iscsi_flashnode_conn_attr(fnode, tcp_timestamp_enable, | ||
| 718 | ISCSI_FLASHNODE_TCP_TIMESTAMP_EN); | ||
| 719 | iscsi_flashnode_conn_attr(fnode, fragment_disable, | ||
| 720 | ISCSI_FLASHNODE_IP_FRAG_DISABLE); | ||
| 721 | iscsi_flashnode_conn_attr(fnode, keepalive_tmo, ISCSI_FLASHNODE_KEEPALIVE_TMO); | ||
| 722 | iscsi_flashnode_conn_attr(fnode, port, ISCSI_FLASHNODE_PORT); | ||
| 723 | iscsi_flashnode_conn_attr(fnode, ipaddress, ISCSI_FLASHNODE_IPADDR); | ||
| 724 | iscsi_flashnode_conn_attr(fnode, max_recv_dlength, | ||
| 725 | ISCSI_FLASHNODE_MAX_RECV_DLENGTH); | ||
| 726 | iscsi_flashnode_conn_attr(fnode, max_xmit_dlength, | ||
| 727 | ISCSI_FLASHNODE_MAX_XMIT_DLENGTH); | ||
| 728 | iscsi_flashnode_conn_attr(fnode, local_port, ISCSI_FLASHNODE_LOCAL_PORT); | ||
| 729 | iscsi_flashnode_conn_attr(fnode, ipv4_tos, ISCSI_FLASHNODE_IPV4_TOS); | ||
| 730 | iscsi_flashnode_conn_attr(fnode, ipv6_traffic_class, ISCSI_FLASHNODE_IPV6_TC); | ||
| 731 | iscsi_flashnode_conn_attr(fnode, ipv6_flow_label, | ||
| 732 | ISCSI_FLASHNODE_IPV6_FLOW_LABEL); | ||
| 733 | iscsi_flashnode_conn_attr(fnode, redirect_ipaddr, | ||
| 734 | ISCSI_FLASHNODE_REDIRECT_IPADDR); | ||
| 735 | iscsi_flashnode_conn_attr(fnode, max_segment_size, | ||
| 736 | ISCSI_FLASHNODE_MAX_SEGMENT_SIZE); | ||
| 737 | iscsi_flashnode_conn_attr(fnode, link_local_ipv6, | ||
| 738 | ISCSI_FLASHNODE_LINK_LOCAL_IPV6); | ||
| 739 | iscsi_flashnode_conn_attr(fnode, tcp_xmit_wsf, ISCSI_FLASHNODE_TCP_XMIT_WSF); | ||
| 740 | iscsi_flashnode_conn_attr(fnode, tcp_recv_wsf, ISCSI_FLASHNODE_TCP_RECV_WSF); | ||
| 741 | iscsi_flashnode_conn_attr(fnode, statsn, ISCSI_FLASHNODE_STATSN); | ||
| 742 | iscsi_flashnode_conn_attr(fnode, exp_statsn, ISCSI_FLASHNODE_EXP_STATSN); | ||
| 743 | |||
| 744 | static struct attribute *iscsi_flashnode_conn_attrs[] = { | ||
| 745 | &dev_attr_fnode_is_fw_assigned_ipv6.attr, | ||
| 746 | &dev_attr_fnode_header_digest.attr, | ||
| 747 | &dev_attr_fnode_data_digest.attr, | ||
| 748 | &dev_attr_fnode_snack_req.attr, | ||
| 749 | &dev_attr_fnode_tcp_timestamp_stat.attr, | ||
| 750 | &dev_attr_fnode_tcp_nagle_disable.attr, | ||
| 751 | &dev_attr_fnode_tcp_wsf_disable.attr, | ||
| 752 | &dev_attr_fnode_tcp_timer_scale.attr, | ||
| 753 | &dev_attr_fnode_tcp_timestamp_enable.attr, | ||
| 754 | &dev_attr_fnode_fragment_disable.attr, | ||
| 755 | &dev_attr_fnode_max_recv_dlength.attr, | ||
| 756 | &dev_attr_fnode_max_xmit_dlength.attr, | ||
| 757 | &dev_attr_fnode_keepalive_tmo.attr, | ||
| 758 | &dev_attr_fnode_port.attr, | ||
| 759 | &dev_attr_fnode_ipaddress.attr, | ||
| 760 | &dev_attr_fnode_redirect_ipaddr.attr, | ||
| 761 | &dev_attr_fnode_max_segment_size.attr, | ||
| 762 | &dev_attr_fnode_local_port.attr, | ||
| 763 | &dev_attr_fnode_ipv4_tos.attr, | ||
| 764 | &dev_attr_fnode_ipv6_traffic_class.attr, | ||
| 765 | &dev_attr_fnode_ipv6_flow_label.attr, | ||
| 766 | &dev_attr_fnode_link_local_ipv6.attr, | ||
| 767 | &dev_attr_fnode_tcp_xmit_wsf.attr, | ||
| 768 | &dev_attr_fnode_tcp_recv_wsf.attr, | ||
| 769 | &dev_attr_fnode_statsn.attr, | ||
| 770 | &dev_attr_fnode_exp_statsn.attr, | ||
| 771 | NULL, | ||
| 772 | }; | ||
| 773 | |||
| 774 | static umode_t iscsi_flashnode_conn_attr_is_visible(struct kobject *kobj, | ||
| 775 | struct attribute *attr, | ||
| 776 | int i) | ||
| 777 | { | ||
| 778 | struct device *dev = container_of(kobj, struct device, kobj); | ||
| 779 | struct iscsi_bus_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev); | ||
| 780 | struct iscsi_transport *t = fnode_conn->transport; | ||
| 781 | int param; | ||
| 782 | |||
| 783 | if (attr == &dev_attr_fnode_is_fw_assigned_ipv6.attr) { | ||
| 784 | param = ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6; | ||
| 785 | } else if (attr == &dev_attr_fnode_header_digest.attr) { | ||
| 786 | param = ISCSI_FLASHNODE_HDR_DGST_EN; | ||
| 787 | } else if (attr == &dev_attr_fnode_data_digest.attr) { | ||
| 788 | param = ISCSI_FLASHNODE_DATA_DGST_EN; | ||
| 789 | } else if (attr == &dev_attr_fnode_snack_req.attr) { | ||
| 790 | param = ISCSI_FLASHNODE_SNACK_REQ_EN; | ||
| 791 | } else if (attr == &dev_attr_fnode_tcp_timestamp_stat.attr) { | ||
| 792 | param = ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT; | ||
| 793 | } else if (attr == &dev_attr_fnode_tcp_nagle_disable.attr) { | ||
| 794 | param = ISCSI_FLASHNODE_TCP_NAGLE_DISABLE; | ||
| 795 | } else if (attr == &dev_attr_fnode_tcp_wsf_disable.attr) { | ||
| 796 | param = ISCSI_FLASHNODE_TCP_WSF_DISABLE; | ||
| 797 | } else if (attr == &dev_attr_fnode_tcp_timer_scale.attr) { | ||
| 798 | param = ISCSI_FLASHNODE_TCP_TIMER_SCALE; | ||
| 799 | } else if (attr == &dev_attr_fnode_tcp_timestamp_enable.attr) { | ||
| 800 | param = ISCSI_FLASHNODE_TCP_TIMESTAMP_EN; | ||
| 801 | } else if (attr == &dev_attr_fnode_fragment_disable.attr) { | ||
| 802 | param = ISCSI_FLASHNODE_IP_FRAG_DISABLE; | ||
| 803 | } else if (attr == &dev_attr_fnode_max_recv_dlength.attr) { | ||
| 804 | param = ISCSI_FLASHNODE_MAX_RECV_DLENGTH; | ||
| 805 | } else if (attr == &dev_attr_fnode_max_xmit_dlength.attr) { | ||
| 806 | param = ISCSI_FLASHNODE_MAX_XMIT_DLENGTH; | ||
| 807 | } else if (attr == &dev_attr_fnode_keepalive_tmo.attr) { | ||
| 808 | param = ISCSI_FLASHNODE_KEEPALIVE_TMO; | ||
| 809 | } else if (attr == &dev_attr_fnode_port.attr) { | ||
| 810 | param = ISCSI_FLASHNODE_PORT; | ||
| 811 | } else if (attr == &dev_attr_fnode_ipaddress.attr) { | ||
| 812 | param = ISCSI_FLASHNODE_IPADDR; | ||
| 813 | } else if (attr == &dev_attr_fnode_redirect_ipaddr.attr) { | ||
| 814 | param = ISCSI_FLASHNODE_REDIRECT_IPADDR; | ||
| 815 | } else if (attr == &dev_attr_fnode_max_segment_size.attr) { | ||
| 816 | param = ISCSI_FLASHNODE_MAX_SEGMENT_SIZE; | ||
| 817 | } else if (attr == &dev_attr_fnode_local_port.attr) { | ||
| 818 | param = ISCSI_FLASHNODE_LOCAL_PORT; | ||
| 819 | } else if (attr == &dev_attr_fnode_ipv4_tos.attr) { | ||
| 820 | param = ISCSI_FLASHNODE_IPV4_TOS; | ||
| 821 | } else if (attr == &dev_attr_fnode_ipv6_traffic_class.attr) { | ||
| 822 | param = ISCSI_FLASHNODE_IPV6_TC; | ||
| 823 | } else if (attr == &dev_attr_fnode_ipv6_flow_label.attr) { | ||
| 824 | param = ISCSI_FLASHNODE_IPV6_FLOW_LABEL; | ||
| 825 | } else if (attr == &dev_attr_fnode_link_local_ipv6.attr) { | ||
| 826 | param = ISCSI_FLASHNODE_LINK_LOCAL_IPV6; | ||
| 827 | } else if (attr == &dev_attr_fnode_tcp_xmit_wsf.attr) { | ||
| 828 | param = ISCSI_FLASHNODE_TCP_XMIT_WSF; | ||
| 829 | } else if (attr == &dev_attr_fnode_tcp_recv_wsf.attr) { | ||
| 830 | param = ISCSI_FLASHNODE_TCP_RECV_WSF; | ||
| 831 | } else if (attr == &dev_attr_fnode_statsn.attr) { | ||
| 832 | param = ISCSI_FLASHNODE_STATSN; | ||
| 833 | } else if (attr == &dev_attr_fnode_exp_statsn.attr) { | ||
| 834 | param = ISCSI_FLASHNODE_EXP_STATSN; | ||
| 835 | } else { | ||
| 836 | WARN_ONCE(1, "Invalid flashnode connection attr"); | ||
| 837 | return 0; | ||
| 838 | } | ||
| 839 | |||
| 840 | return t->attr_is_visible(ISCSI_FLASHNODE_PARAM, param); | ||
| 841 | } | ||
| 842 | |||
| 843 | static struct attribute_group iscsi_flashnode_conn_attr_group = { | ||
| 844 | .attrs = iscsi_flashnode_conn_attrs, | ||
| 845 | .is_visible = iscsi_flashnode_conn_attr_is_visible, | ||
| 846 | }; | ||
| 847 | |||
| 848 | static const struct attribute_group *iscsi_flashnode_conn_attr_groups[] = { | ||
| 849 | &iscsi_flashnode_conn_attr_group, | ||
| 850 | NULL, | ||
| 851 | }; | ||
| 852 | |||
| 853 | static void iscsi_flashnode_conn_release(struct device *dev) | ||
| 854 | { | ||
| 855 | struct iscsi_bus_flash_conn *fnode_conn = iscsi_dev_to_flash_conn(dev); | ||
| 856 | |||
| 857 | kfree(fnode_conn->ipaddress); | ||
| 858 | kfree(fnode_conn->redirect_ipaddr); | ||
| 859 | kfree(fnode_conn->link_local_ipv6_addr); | ||
| 860 | kfree(fnode_conn); | ||
| 861 | } | ||
| 862 | |||
| 863 | struct device_type iscsi_flashnode_conn_dev_type = { | ||
| 864 | .name = "iscsi_flashnode_conn_dev_type", | ||
| 865 | .groups = iscsi_flashnode_conn_attr_groups, | ||
| 866 | .release = iscsi_flashnode_conn_release, | ||
| 867 | }; | ||
| 868 | |||
| 869 | struct bus_type iscsi_flashnode_bus; | ||
| 870 | |||
| 871 | int iscsi_flashnode_bus_match(struct device *dev, | ||
| 872 | struct device_driver *drv) | ||
| 873 | { | ||
| 874 | if (dev->bus == &iscsi_flashnode_bus) | ||
| 875 | return 1; | ||
| 876 | return 0; | ||
| 877 | } | ||
| 878 | EXPORT_SYMBOL_GPL(iscsi_flashnode_bus_match); | ||
| 879 | |||
| 880 | struct bus_type iscsi_flashnode_bus = { | ||
| 881 | .name = "iscsi_flashnode", | ||
| 882 | .match = &iscsi_flashnode_bus_match, | ||
| 883 | }; | ||
| 884 | |||
| 885 | /** | ||
| 886 | * iscsi_create_flashnode_sess - Add flashnode session entry in sysfs | ||
| 887 | * @shost: pointer to host data | ||
| 888 | * @index: index of flashnode to add in sysfs | ||
| 889 | * @transport: pointer to transport data | ||
| 890 | * @dd_size: total size to allocate | ||
| 891 | * | ||
| 892 | * Adds a sysfs entry for the flashnode session attributes | ||
| 893 | * | ||
| 894 | * Returns: | ||
| 895 | * pointer to allocated flashnode sess on sucess | ||
| 896 | * %NULL on failure | ||
| 897 | */ | ||
| 898 | struct iscsi_bus_flash_session * | ||
| 899 | iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index, | ||
| 900 | struct iscsi_transport *transport, | ||
| 901 | int dd_size) | ||
| 902 | { | ||
| 903 | struct iscsi_bus_flash_session *fnode_sess; | ||
| 904 | int err; | ||
| 905 | |||
| 906 | fnode_sess = kzalloc(sizeof(*fnode_sess) + dd_size, GFP_KERNEL); | ||
| 907 | if (!fnode_sess) | ||
| 908 | return NULL; | ||
| 909 | |||
| 910 | fnode_sess->transport = transport; | ||
| 911 | fnode_sess->target_id = index; | ||
| 912 | fnode_sess->dev.type = &iscsi_flashnode_sess_dev_type; | ||
| 913 | fnode_sess->dev.bus = &iscsi_flashnode_bus; | ||
| 914 | fnode_sess->dev.parent = &shost->shost_gendev; | ||
| 915 | dev_set_name(&fnode_sess->dev, "flashnode_sess-%u:%u", | ||
| 916 | shost->host_no, index); | ||
| 917 | |||
| 918 | err = device_register(&fnode_sess->dev); | ||
| 919 | if (err) | ||
| 920 | goto free_fnode_sess; | ||
| 921 | |||
| 922 | if (dd_size) | ||
| 923 | fnode_sess->dd_data = &fnode_sess[1]; | ||
| 924 | |||
| 925 | return fnode_sess; | ||
| 926 | |||
| 927 | free_fnode_sess: | ||
| 928 | kfree(fnode_sess); | ||
| 929 | return NULL; | ||
| 930 | } | ||
| 931 | EXPORT_SYMBOL_GPL(iscsi_create_flashnode_sess); | ||
| 932 | |||
| 933 | /** | ||
| 934 | * iscsi_create_flashnode_conn - Add flashnode conn entry in sysfs | ||
| 935 | * @shost: pointer to host data | ||
| 936 | * @fnode_sess: pointer to the parent flashnode session entry | ||
| 937 | * @transport: pointer to transport data | ||
| 938 | * @dd_size: total size to allocate | ||
| 939 | * | ||
| 940 | * Adds a sysfs entry for the flashnode connection attributes | ||
| 941 | * | ||
| 942 | * Returns: | ||
| 943 | * pointer to allocated flashnode conn on success | ||
| 944 | * %NULL on failure | ||
| 945 | */ | ||
| 946 | struct iscsi_bus_flash_conn * | ||
| 947 | iscsi_create_flashnode_conn(struct Scsi_Host *shost, | ||
| 948 | struct iscsi_bus_flash_session *fnode_sess, | ||
| 949 | struct iscsi_transport *transport, | ||
| 950 | int dd_size) | ||
| 951 | { | ||
| 952 | struct iscsi_bus_flash_conn *fnode_conn; | ||
| 953 | int err; | ||
| 954 | |||
| 955 | fnode_conn = kzalloc(sizeof(*fnode_conn) + dd_size, GFP_KERNEL); | ||
| 956 | if (!fnode_conn) | ||
| 957 | return NULL; | ||
| 958 | |||
| 959 | fnode_conn->transport = transport; | ||
| 960 | fnode_conn->dev.type = &iscsi_flashnode_conn_dev_type; | ||
| 961 | fnode_conn->dev.bus = &iscsi_flashnode_bus; | ||
| 962 | fnode_conn->dev.parent = &fnode_sess->dev; | ||
| 963 | dev_set_name(&fnode_conn->dev, "flashnode_conn-%u:%u:0", | ||
| 964 | shost->host_no, fnode_sess->target_id); | ||
| 965 | |||
| 966 | err = device_register(&fnode_conn->dev); | ||
| 967 | if (err) | ||
| 968 | goto free_fnode_conn; | ||
| 969 | |||
| 970 | if (dd_size) | ||
| 971 | fnode_conn->dd_data = &fnode_conn[1]; | ||
| 972 | |||
| 973 | return fnode_conn; | ||
| 974 | |||
| 975 | free_fnode_conn: | ||
| 976 | kfree(fnode_conn); | ||
| 977 | return NULL; | ||
| 978 | } | ||
| 979 | EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn); | ||
| 980 | |||
| 981 | /** | ||
| 982 | * iscsi_is_flashnode_conn_dev - verify passed device is to be flashnode conn | ||
| 983 | * @dev: device to verify | ||
| 984 | * @data: pointer to data containing value to use for verification | ||
| 985 | * | ||
| 986 | * Verifies if the passed device is flashnode conn device | ||
| 987 | * | ||
| 988 | * Returns: | ||
| 989 | * 1 on success | ||
| 990 | * 0 on failure | ||
| 991 | */ | ||
| 992 | int iscsi_is_flashnode_conn_dev(struct device *dev, void *data) | ||
| 993 | { | ||
| 994 | return dev->bus == &iscsi_flashnode_bus; | ||
| 995 | } | ||
| 996 | EXPORT_SYMBOL_GPL(iscsi_is_flashnode_conn_dev); | ||
| 997 | |||
| 998 | static int iscsi_destroy_flashnode_conn(struct iscsi_bus_flash_conn *fnode_conn) | ||
| 999 | { | ||
| 1000 | device_unregister(&fnode_conn->dev); | ||
| 1001 | return 0; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | static int flashnode_match_index(struct device *dev, void *data) | ||
| 1005 | { | ||
| 1006 | struct iscsi_bus_flash_session *fnode_sess = NULL; | ||
| 1007 | int ret = 0; | ||
| 1008 | |||
| 1009 | if (!iscsi_flashnode_bus_match(dev, NULL)) | ||
| 1010 | goto exit_match_index; | ||
| 1011 | |||
| 1012 | fnode_sess = iscsi_dev_to_flash_session(dev); | ||
| 1013 | ret = (fnode_sess->target_id == *((int *)data)) ? 1 : 0; | ||
| 1014 | |||
| 1015 | exit_match_index: | ||
| 1016 | return ret; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | /** | ||
| 1020 | * iscsi_get_flashnode_by_index -finds flashnode session entry by index | ||
| 1021 | * @shost: pointer to host data | ||
| 1022 | * @data: pointer to data containing value to use for comparison | ||
| 1023 | * @fn: function pointer that does actual comparison | ||
| 1024 | * | ||
| 1025 | * Finds the flashnode session object for the passed index | ||
| 1026 | * | ||
| 1027 | * Returns: | ||
| 1028 | * pointer to found flashnode session object on success | ||
| 1029 | * %NULL on failure | ||
| 1030 | */ | ||
| 1031 | static struct iscsi_bus_flash_session * | ||
| 1032 | iscsi_get_flashnode_by_index(struct Scsi_Host *shost, void *data, | ||
| 1033 | int (*fn)(struct device *dev, void *data)) | ||
| 1034 | { | ||
| 1035 | struct iscsi_bus_flash_session *fnode_sess = NULL; | ||
| 1036 | struct device *dev; | ||
| 1037 | |||
| 1038 | dev = device_find_child(&shost->shost_gendev, data, fn); | ||
| 1039 | if (dev) | ||
| 1040 | fnode_sess = iscsi_dev_to_flash_session(dev); | ||
| 1041 | |||
| 1042 | return fnode_sess; | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | /** | ||
| 1046 | * iscsi_find_flashnode_sess - finds flashnode session entry | ||
| 1047 | * @shost: pointer to host data | ||
| 1048 | * @data: pointer to data containing value to use for comparison | ||
| 1049 | * @fn: function pointer that does actual comparison | ||
| 1050 | * | ||
| 1051 | * Finds the flashnode session object comparing the data passed using logic | ||
| 1052 | * defined in passed function pointer | ||
| 1053 | * | ||
| 1054 | * Returns: | ||
| 1055 | * pointer to found flashnode session device object on success | ||
| 1056 | * %NULL on failure | ||
| 1057 | */ | ||
| 1058 | struct device * | ||
| 1059 | iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data, | ||
| 1060 | int (*fn)(struct device *dev, void *data)) | ||
| 1061 | { | ||
| 1062 | struct device *dev; | ||
| 1063 | |||
| 1064 | dev = device_find_child(&shost->shost_gendev, data, fn); | ||
| 1065 | return dev; | ||
| 1066 | } | ||
| 1067 | EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess); | ||
| 1068 | |||
| 1069 | /** | ||
| 1070 | * iscsi_find_flashnode_conn - finds flashnode connection entry | ||
| 1071 | * @fnode_sess: pointer to parent flashnode session entry | ||
| 1072 | * @data: pointer to data containing value to use for comparison | ||
| 1073 | * @fn: function pointer that does actual comparison | ||
| 1074 | * | ||
| 1075 | * Finds the flashnode connection object comparing the data passed using logic | ||
| 1076 | * defined in passed function pointer | ||
| 1077 | * | ||
| 1078 | * Returns: | ||
| 1079 | * pointer to found flashnode connection device object on success | ||
| 1080 | * %NULL on failure | ||
| 1081 | */ | ||
| 1082 | struct device * | ||
| 1083 | iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess, | ||
| 1084 | void *data, | ||
| 1085 | int (*fn)(struct device *dev, void *data)) | ||
| 1086 | { | ||
| 1087 | struct device *dev; | ||
| 1088 | |||
| 1089 | dev = device_find_child(&fnode_sess->dev, data, fn); | ||
| 1090 | return dev; | ||
| 1091 | } | ||
| 1092 | EXPORT_SYMBOL_GPL(iscsi_find_flashnode_conn); | ||
| 1093 | |||
| 1094 | static int iscsi_iter_destroy_flashnode_conn_fn(struct device *dev, void *data) | ||
| 1095 | { | ||
| 1096 | if (!iscsi_is_flashnode_conn_dev(dev, NULL)) | ||
| 1097 | return 0; | ||
| 1098 | |||
| 1099 | return iscsi_destroy_flashnode_conn(iscsi_dev_to_flash_conn(dev)); | ||
| 1100 | } | ||
| 1101 | |||
| 1102 | /** | ||
| 1103 | * iscsi_destroy_flashnode_sess - destory flashnode session entry | ||
| 1104 | * @fnode_sess: pointer to flashnode session entry to be destroyed | ||
| 1105 | * | ||
| 1106 | * Deletes the flashnode session entry and all children flashnode connection | ||
| 1107 | * entries from sysfs | ||
| 1108 | */ | ||
| 1109 | void iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess) | ||
| 1110 | { | ||
| 1111 | int err; | ||
| 1112 | |||
| 1113 | err = device_for_each_child(&fnode_sess->dev, NULL, | ||
| 1114 | iscsi_iter_destroy_flashnode_conn_fn); | ||
| 1115 | if (err) | ||
| 1116 | pr_err("Could not delete all connections for %s. Error %d.\n", | ||
| 1117 | fnode_sess->dev.kobj.name, err); | ||
| 1118 | |||
| 1119 | device_unregister(&fnode_sess->dev); | ||
| 1120 | } | ||
| 1121 | EXPORT_SYMBOL_GPL(iscsi_destroy_flashnode_sess); | ||
| 1122 | |||
| 1123 | static int iscsi_iter_destroy_flashnode_fn(struct device *dev, void *data) | ||
| 1124 | { | ||
| 1125 | if (!iscsi_flashnode_bus_match(dev, NULL)) | ||
| 1126 | return 0; | ||
| 1127 | |||
| 1128 | iscsi_destroy_flashnode_sess(iscsi_dev_to_flash_session(dev)); | ||
| 1129 | return 0; | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | /** | ||
| 1133 | * iscsi_destroy_all_flashnode - destory all flashnode session entries | ||
| 1134 | * @shost: pointer to host data | ||
| 1135 | * | ||
| 1136 | * Destroys all the flashnode session entries and all corresponding children | ||
| 1137 | * flashnode connection entries from sysfs | ||
| 1138 | */ | ||
| 1139 | void iscsi_destroy_all_flashnode(struct Scsi_Host *shost) | ||
| 1140 | { | ||
| 1141 | device_for_each_child(&shost->shost_gendev, NULL, | ||
| 1142 | iscsi_iter_destroy_flashnode_fn); | ||
| 1143 | } | ||
| 1144 | EXPORT_SYMBOL_GPL(iscsi_destroy_all_flashnode); | ||
| 1145 | |||
| 1146 | /* | ||
| 463 | * BSG support | 1147 | * BSG support |
| 464 | */ | 1148 | */ |
| 465 | /** | 1149 | /** |
| @@ -2092,6 +2776,294 @@ static int iscsi_delete_chap(struct iscsi_transport *transport, | |||
| 2092 | return err; | 2776 | return err; |
| 2093 | } | 2777 | } |
| 2094 | 2778 | ||
| 2779 | static const struct { | ||
| 2780 | enum iscsi_discovery_parent_type value; | ||
| 2781 | char *name; | ||
| 2782 | } iscsi_discovery_parent_names[] = { | ||
| 2783 | {ISCSI_DISC_PARENT_UNKNOWN, "Unknown" }, | ||
| 2784 | {ISCSI_DISC_PARENT_SENDTGT, "Sendtarget" }, | ||
| 2785 | {ISCSI_DISC_PARENT_ISNS, "isns" }, | ||
| 2786 | }; | ||
| 2787 | |||
| 2788 | char *iscsi_get_discovery_parent_name(int parent_type) | ||
| 2789 | { | ||
| 2790 | int i; | ||
| 2791 | char *state = "Unknown!"; | ||
| 2792 | |||
| 2793 | for (i = 0; i < ARRAY_SIZE(iscsi_discovery_parent_names); i++) { | ||
| 2794 | if (iscsi_discovery_parent_names[i].value & parent_type) { | ||
| 2795 | state = iscsi_discovery_parent_names[i].name; | ||
| 2796 | break; | ||
| 2797 | } | ||
| 2798 | } | ||
| 2799 | return state; | ||
| 2800 | } | ||
| 2801 | EXPORT_SYMBOL_GPL(iscsi_get_discovery_parent_name); | ||
| 2802 | |||
| 2803 | static int iscsi_set_flashnode_param(struct iscsi_transport *transport, | ||
| 2804 | struct iscsi_uevent *ev, uint32_t len) | ||
| 2805 | { | ||
| 2806 | char *data = (char *)ev + sizeof(*ev); | ||
| 2807 | struct Scsi_Host *shost; | ||
| 2808 | struct iscsi_bus_flash_session *fnode_sess; | ||
| 2809 | struct iscsi_bus_flash_conn *fnode_conn; | ||
| 2810 | struct device *dev; | ||
| 2811 | uint32_t *idx; | ||
| 2812 | int err = 0; | ||
| 2813 | |||
| 2814 | if (!transport->set_flashnode_param) { | ||
| 2815 | err = -ENOSYS; | ||
| 2816 | goto exit_set_fnode; | ||
| 2817 | } | ||
| 2818 | |||
| 2819 | shost = scsi_host_lookup(ev->u.set_flashnode.host_no); | ||
| 2820 | if (!shost) { | ||
| 2821 | pr_err("%s could not find host no %u\n", | ||
| 2822 | __func__, ev->u.set_flashnode.host_no); | ||
| 2823 | err = -ENODEV; | ||
| 2824 | goto put_host; | ||
| 2825 | } | ||
| 2826 | |||
| 2827 | idx = &ev->u.set_flashnode.flashnode_idx; | ||
| 2828 | fnode_sess = iscsi_get_flashnode_by_index(shost, idx, | ||
| 2829 | flashnode_match_index); | ||
| 2830 | if (!fnode_sess) { | ||
| 2831 | pr_err("%s could not find flashnode %u for host no %u\n", | ||
| 2832 | __func__, *idx, ev->u.set_flashnode.host_no); | ||
| 2833 | err = -ENODEV; | ||
| 2834 | goto put_host; | ||
| 2835 | } | ||
| 2836 | |||
| 2837 | dev = iscsi_find_flashnode_conn(fnode_sess, NULL, | ||
| 2838 | iscsi_is_flashnode_conn_dev); | ||
| 2839 | if (!dev) { | ||
| 2840 | err = -ENODEV; | ||
| 2841 | goto put_host; | ||
| 2842 | } | ||
| 2843 | |||
| 2844 | fnode_conn = iscsi_dev_to_flash_conn(dev); | ||
| 2845 | err = transport->set_flashnode_param(fnode_sess, fnode_conn, data, len); | ||
| 2846 | |||
| 2847 | put_host: | ||
| 2848 | scsi_host_put(shost); | ||
| 2849 | |||
| 2850 | exit_set_fnode: | ||
| 2851 | return err; | ||
| 2852 | } | ||
| 2853 | |||
| 2854 | static int iscsi_new_flashnode(struct iscsi_transport *transport, | ||
| 2855 | struct iscsi_uevent *ev, uint32_t len) | ||
| 2856 | { | ||
| 2857 | char *data = (char *)ev + sizeof(*ev); | ||
| 2858 | struct Scsi_Host *shost; | ||
| 2859 | int index; | ||
| 2860 | int err = 0; | ||
| 2861 | |||
| 2862 | if (!transport->new_flashnode) { | ||
| 2863 | err = -ENOSYS; | ||
| 2864 | goto exit_new_fnode; | ||
| 2865 | } | ||
| 2866 | |||
| 2867 | shost = scsi_host_lookup(ev->u.new_flashnode.host_no); | ||
| 2868 | if (!shost) { | ||
| 2869 | pr_err("%s could not find host no %u\n", | ||
| 2870 | __func__, ev->u.new_flashnode.host_no); | ||
| 2871 | err = -ENODEV; | ||
| 2872 | goto put_host; | ||
| 2873 | } | ||
| 2874 | |||
| 2875 | index = transport->new_flashnode(shost, data, len); | ||
| 2876 | |||
| 2877 | if (index >= 0) | ||
| 2878 | ev->r.new_flashnode_ret.flashnode_idx = index; | ||
| 2879 | else | ||
| 2880 | err = -EIO; | ||
| 2881 | |||
| 2882 | put_host: | ||
| 2883 | scsi_host_put(shost); | ||
| 2884 | |||
| 2885 | exit_new_fnode: | ||
| 2886 | return err; | ||
| 2887 | } | ||
| 2888 | |||
| 2889 | static int iscsi_del_flashnode(struct iscsi_transport *transport, | ||
| 2890 | struct iscsi_uevent *ev) | ||
| 2891 | { | ||
| 2892 | struct Scsi_Host *shost; | ||
| 2893 | struct iscsi_bus_flash_session *fnode_sess; | ||
| 2894 | uint32_t *idx; | ||
| 2895 | int err = 0; | ||
| 2896 | |||
| 2897 | if (!transport->del_flashnode) { | ||
| 2898 | err = -ENOSYS; | ||
| 2899 | goto exit_del_fnode; | ||
| 2900 | } | ||
| 2901 | |||
| 2902 | shost = scsi_host_lookup(ev->u.del_flashnode.host_no); | ||
| 2903 | if (!shost) { | ||
| 2904 | pr_err("%s could not find host no %u\n", | ||
| 2905 | __func__, ev->u.del_flashnode.host_no); | ||
| 2906 | err = -ENODEV; | ||
| 2907 | goto put_host; | ||
| 2908 | } | ||
| 2909 | |||
| 2910 | idx = &ev->u.del_flashnode.flashnode_idx; | ||
| 2911 | fnode_sess = iscsi_get_flashnode_by_index(shost, idx, | ||
| 2912 | flashnode_match_index); | ||
| 2913 | if (!fnode_sess) { | ||
| 2914 | pr_err("%s could not find flashnode %u for host no %u\n", | ||
| 2915 | __func__, *idx, ev->u.del_flashnode.host_no); | ||
| 2916 | err = -ENODEV; | ||
| 2917 | goto put_host; | ||
| 2918 | } | ||
| 2919 | |||
| 2920 | err = transport->del_flashnode(fnode_sess); | ||
| 2921 | |||
| 2922 | put_host: | ||
| 2923 | scsi_host_put(shost); | ||
| 2924 | |||
| 2925 | exit_del_fnode: | ||
| 2926 | return err; | ||
| 2927 | } | ||
| 2928 | |||
| 2929 | static int iscsi_login_flashnode(struct iscsi_transport *transport, | ||
| 2930 | struct iscsi_uevent *ev) | ||
| 2931 | { | ||
| 2932 | struct Scsi_Host *shost; | ||
| 2933 | struct iscsi_bus_flash_session *fnode_sess; | ||
| 2934 | struct iscsi_bus_flash_conn *fnode_conn; | ||
| 2935 | struct device *dev; | ||
| 2936 | uint32_t *idx; | ||
| 2937 | int err = 0; | ||
| 2938 | |||
| 2939 | if (!transport->login_flashnode) { | ||
| 2940 | err = -ENOSYS; | ||
| 2941 | goto exit_login_fnode; | ||
| 2942 | } | ||
| 2943 | |||
| 2944 | shost = scsi_host_lookup(ev->u.login_flashnode.host_no); | ||
| 2945 | if (!shost) { | ||
| 2946 | pr_err("%s could not find host no %u\n", | ||
| 2947 | __func__, ev->u.login_flashnode.host_no); | ||
| 2948 | err = -ENODEV; | ||
| 2949 | goto put_host; | ||
| 2950 | } | ||
| 2951 | |||
| 2952 | idx = &ev->u.login_flashnode.flashnode_idx; | ||
| 2953 | fnode_sess = iscsi_get_flashnode_by_index(shost, idx, | ||
| 2954 | flashnode_match_index); | ||
| 2955 | if (!fnode_sess) { | ||
| 2956 | pr_err("%s could not find flashnode %u for host no %u\n", | ||
| 2957 | __func__, *idx, ev->u.login_flashnode.host_no); | ||
| 2958 | err = -ENODEV; | ||
| 2959 | goto put_host; | ||
| 2960 | } | ||
| 2961 | |||
| 2962 | dev = iscsi_find_flashnode_conn(fnode_sess, NULL, | ||
| 2963 | iscsi_is_flashnode_conn_dev); | ||
| 2964 | if (!dev) { | ||
| 2965 | err = -ENODEV; | ||
| 2966 | goto put_host; | ||
| 2967 | } | ||
| 2968 | |||
| 2969 | fnode_conn = iscsi_dev_to_flash_conn(dev); | ||
| 2970 | err = transport->login_flashnode(fnode_sess, fnode_conn); | ||
| 2971 | |||
| 2972 | put_host: | ||
| 2973 | scsi_host_put(shost); | ||
| 2974 | |||
| 2975 | exit_login_fnode: | ||
| 2976 | return err; | ||
| 2977 | } | ||
| 2978 | |||
| 2979 | static int iscsi_logout_flashnode(struct iscsi_transport *transport, | ||
| 2980 | struct iscsi_uevent *ev) | ||
| 2981 | { | ||
| 2982 | struct Scsi_Host *shost; | ||
| 2983 | struct iscsi_bus_flash_session *fnode_sess; | ||
| 2984 | struct iscsi_bus_flash_conn *fnode_conn; | ||
| 2985 | struct device *dev; | ||
| 2986 | uint32_t *idx; | ||
| 2987 | int err = 0; | ||
| 2988 | |||
| 2989 | if (!transport->logout_flashnode) { | ||
| 2990 | err = -ENOSYS; | ||
| 2991 | goto exit_logout_fnode; | ||
| 2992 | } | ||
| 2993 | |||
| 2994 | shost = scsi_host_lookup(ev->u.logout_flashnode.host_no); | ||
| 2995 | if (!shost) { | ||
| 2996 | pr_err("%s could not find host no %u\n", | ||
| 2997 | __func__, ev->u.logout_flashnode.host_no); | ||
| 2998 | err = -ENODEV; | ||
| 2999 | goto put_host; | ||
| 3000 | } | ||
| 3001 | |||
| 3002 | idx = &ev->u.logout_flashnode.flashnode_idx; | ||
| 3003 | fnode_sess = iscsi_get_flashnode_by_index(shost, idx, | ||
| 3004 | flashnode_match_index); | ||
| 3005 | if (!fnode_sess) { | ||
| 3006 | pr_err("%s could not find flashnode %u for host no %u\n", | ||
| 3007 | __func__, *idx, ev->u.logout_flashnode.host_no); | ||
| 3008 | err = -ENODEV; | ||
| 3009 | goto put_host; | ||
| 3010 | } | ||
| 3011 | |||
| 3012 | dev = iscsi_find_flashnode_conn(fnode_sess, NULL, | ||
| 3013 | iscsi_is_flashnode_conn_dev); | ||
| 3014 | if (!dev) { | ||
| 3015 | err = -ENODEV; | ||
| 3016 | goto put_host; | ||
| 3017 | } | ||
| 3018 | |||
| 3019 | fnode_conn = iscsi_dev_to_flash_conn(dev); | ||
| 3020 | |||
| 3021 | err = transport->logout_flashnode(fnode_sess, fnode_conn); | ||
| 3022 | |||
| 3023 | put_host: | ||
| 3024 | scsi_host_put(shost); | ||
| 3025 | |||
| 3026 | exit_logout_fnode: | ||
| 3027 | return err; | ||
| 3028 | } | ||
| 3029 | |||
| 3030 | static int iscsi_logout_flashnode_sid(struct iscsi_transport *transport, | ||
| 3031 | struct iscsi_uevent *ev) | ||
| 3032 | { | ||
| 3033 | struct Scsi_Host *shost; | ||
| 3034 | struct iscsi_cls_session *session; | ||
| 3035 | int err = 0; | ||
| 3036 | |||
| 3037 | if (!transport->logout_flashnode_sid) { | ||
| 3038 | err = -ENOSYS; | ||
| 3039 | goto exit_logout_sid; | ||
| 3040 | } | ||
| 3041 | |||
| 3042 | shost = scsi_host_lookup(ev->u.logout_flashnode_sid.host_no); | ||
| 3043 | if (!shost) { | ||
| 3044 | pr_err("%s could not find host no %u\n", | ||
| 3045 | __func__, ev->u.logout_flashnode.host_no); | ||
| 3046 | err = -ENODEV; | ||
| 3047 | goto put_host; | ||
| 3048 | } | ||
| 3049 | |||
| 3050 | session = iscsi_session_lookup(ev->u.logout_flashnode_sid.sid); | ||
| 3051 | if (!session) { | ||
| 3052 | pr_err("%s could not find session id %u\n", | ||
| 3053 | __func__, ev->u.logout_flashnode_sid.sid); | ||
| 3054 | err = -EINVAL; | ||
| 3055 | goto put_host; | ||
| 3056 | } | ||
| 3057 | |||
| 3058 | err = transport->logout_flashnode_sid(session); | ||
| 3059 | |||
| 3060 | put_host: | ||
| 3061 | scsi_host_put(shost); | ||
| 3062 | |||
| 3063 | exit_logout_sid: | ||
| 3064 | return err; | ||
| 3065 | } | ||
| 3066 | |||
| 2095 | static int | 3067 | static int |
| 2096 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) | 3068 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) |
| 2097 | { | 3069 | { |
| @@ -2246,6 +3218,27 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) | |||
| 2246 | case ISCSI_UEVENT_DELETE_CHAP: | 3218 | case ISCSI_UEVENT_DELETE_CHAP: |
| 2247 | err = iscsi_delete_chap(transport, ev); | 3219 | err = iscsi_delete_chap(transport, ev); |
| 2248 | break; | 3220 | break; |
| 3221 | case ISCSI_UEVENT_SET_FLASHNODE_PARAMS: | ||
| 3222 | err = iscsi_set_flashnode_param(transport, ev, | ||
| 3223 | nlmsg_attrlen(nlh, | ||
| 3224 | sizeof(*ev))); | ||
| 3225 | break; | ||
| 3226 | case ISCSI_UEVENT_NEW_FLASHNODE: | ||
| 3227 | err = iscsi_new_flashnode(transport, ev, | ||
| 3228 | nlmsg_attrlen(nlh, sizeof(*ev))); | ||
| 3229 | break; | ||
| 3230 | case ISCSI_UEVENT_DEL_FLASHNODE: | ||
| 3231 | err = iscsi_del_flashnode(transport, ev); | ||
| 3232 | break; | ||
| 3233 | case ISCSI_UEVENT_LOGIN_FLASHNODE: | ||
| 3234 | err = iscsi_login_flashnode(transport, ev); | ||
| 3235 | break; | ||
| 3236 | case ISCSI_UEVENT_LOGOUT_FLASHNODE: | ||
| 3237 | err = iscsi_logout_flashnode(transport, ev); | ||
| 3238 | break; | ||
| 3239 | case ISCSI_UEVENT_LOGOUT_FLASHNODE_SID: | ||
| 3240 | err = iscsi_logout_flashnode_sid(transport, ev); | ||
| 3241 | break; | ||
| 2249 | default: | 3242 | default: |
| 2250 | err = -ENOSYS; | 3243 | err = -ENOSYS; |
| 2251 | break; | 3244 | break; |
| @@ -2981,10 +3974,14 @@ static __init int iscsi_transport_init(void) | |||
| 2981 | if (err) | 3974 | if (err) |
| 2982 | goto unregister_conn_class; | 3975 | goto unregister_conn_class; |
| 2983 | 3976 | ||
| 3977 | err = bus_register(&iscsi_flashnode_bus); | ||
| 3978 | if (err) | ||
| 3979 | goto unregister_session_class; | ||
| 3980 | |||
| 2984 | nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, &cfg); | 3981 | nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, &cfg); |
| 2985 | if (!nls) { | 3982 | if (!nls) { |
| 2986 | err = -ENOBUFS; | 3983 | err = -ENOBUFS; |
| 2987 | goto unregister_session_class; | 3984 | goto unregister_flashnode_bus; |
| 2988 | } | 3985 | } |
| 2989 | 3986 | ||
| 2990 | iscsi_eh_timer_workq = create_singlethread_workqueue("iscsi_eh"); | 3987 | iscsi_eh_timer_workq = create_singlethread_workqueue("iscsi_eh"); |
| @@ -2995,6 +3992,8 @@ static __init int iscsi_transport_init(void) | |||
| 2995 | 3992 | ||
| 2996 | release_nls: | 3993 | release_nls: |
| 2997 | netlink_kernel_release(nls); | 3994 | netlink_kernel_release(nls); |
| 3995 | unregister_flashnode_bus: | ||
| 3996 | bus_unregister(&iscsi_flashnode_bus); | ||
| 2998 | unregister_session_class: | 3997 | unregister_session_class: |
| 2999 | transport_class_unregister(&iscsi_session_class); | 3998 | transport_class_unregister(&iscsi_session_class); |
| 3000 | unregister_conn_class: | 3999 | unregister_conn_class: |
| @@ -3014,6 +4013,7 @@ static void __exit iscsi_transport_exit(void) | |||
| 3014 | { | 4013 | { |
| 3015 | destroy_workqueue(iscsi_eh_timer_workq); | 4014 | destroy_workqueue(iscsi_eh_timer_workq); |
| 3016 | netlink_kernel_release(nls); | 4015 | netlink_kernel_release(nls); |
| 4016 | bus_unregister(&iscsi_flashnode_bus); | ||
| 3017 | transport_class_unregister(&iscsi_connection_class); | 4017 | transport_class_unregister(&iscsi_connection_class); |
| 3018 | transport_class_unregister(&iscsi_session_class); | 4018 | transport_class_unregister(&iscsi_session_class); |
| 3019 | transport_class_unregister(&iscsi_host_class); | 4019 | transport_class_unregister(&iscsi_host_class); |
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 917741bb8e11..f1b01839490c 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h | |||
| @@ -63,6 +63,12 @@ enum iscsi_uevent_e { | |||
| 63 | ISCSI_UEVENT_PING = UEVENT_BASE + 22, | 63 | ISCSI_UEVENT_PING = UEVENT_BASE + 22, |
| 64 | ISCSI_UEVENT_GET_CHAP = UEVENT_BASE + 23, | 64 | ISCSI_UEVENT_GET_CHAP = UEVENT_BASE + 23, |
| 65 | ISCSI_UEVENT_DELETE_CHAP = UEVENT_BASE + 24, | 65 | ISCSI_UEVENT_DELETE_CHAP = UEVENT_BASE + 24, |
| 66 | ISCSI_UEVENT_SET_FLASHNODE_PARAMS = UEVENT_BASE + 25, | ||
| 67 | ISCSI_UEVENT_NEW_FLASHNODE = UEVENT_BASE + 26, | ||
| 68 | ISCSI_UEVENT_DEL_FLASHNODE = UEVENT_BASE + 27, | ||
| 69 | ISCSI_UEVENT_LOGIN_FLASHNODE = UEVENT_BASE + 28, | ||
| 70 | ISCSI_UEVENT_LOGOUT_FLASHNODE = UEVENT_BASE + 29, | ||
| 71 | ISCSI_UEVENT_LOGOUT_FLASHNODE_SID = UEVENT_BASE + 30, | ||
| 66 | 72 | ||
| 67 | /* up events */ | 73 | /* up events */ |
| 68 | ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, | 74 | ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, |
| @@ -210,6 +216,31 @@ struct iscsi_uevent { | |||
| 210 | uint32_t host_no; | 216 | uint32_t host_no; |
| 211 | uint16_t chap_tbl_idx; | 217 | uint16_t chap_tbl_idx; |
| 212 | } delete_chap; | 218 | } delete_chap; |
| 219 | struct msg_set_flashnode_param { | ||
| 220 | uint32_t host_no; | ||
| 221 | uint32_t flashnode_idx; | ||
| 222 | uint32_t count; | ||
| 223 | } set_flashnode; | ||
| 224 | struct msg_new_flashnode { | ||
| 225 | uint32_t host_no; | ||
| 226 | uint32_t len; | ||
| 227 | } new_flashnode; | ||
| 228 | struct msg_del_flashnode { | ||
| 229 | uint32_t host_no; | ||
| 230 | uint32_t flashnode_idx; | ||
| 231 | } del_flashnode; | ||
| 232 | struct msg_login_flashnode { | ||
| 233 | uint32_t host_no; | ||
| 234 | uint32_t flashnode_idx; | ||
| 235 | } login_flashnode; | ||
| 236 | struct msg_logout_flashnode { | ||
| 237 | uint32_t host_no; | ||
| 238 | uint32_t flashnode_idx; | ||
| 239 | } logout_flashnode; | ||
| 240 | struct msg_logout_flashnode_sid { | ||
| 241 | uint32_t host_no; | ||
| 242 | uint32_t sid; | ||
| 243 | } logout_flashnode_sid; | ||
| 213 | } u; | 244 | } u; |
| 214 | union { | 245 | union { |
| 215 | /* messages k -> u */ | 246 | /* messages k -> u */ |
| @@ -267,6 +298,9 @@ struct iscsi_uevent { | |||
| 267 | with each ping request */ | 298 | with each ping request */ |
| 268 | uint32_t data_size; | 299 | uint32_t data_size; |
| 269 | } ping_comp; | 300 | } ping_comp; |
| 301 | struct msg_new_flashnode_ret { | ||
| 302 | uint32_t flashnode_idx; | ||
| 303 | } new_flashnode_ret; | ||
| 270 | } r; | 304 | } r; |
| 271 | } __attribute__ ((aligned (sizeof(uint64_t)))); | 305 | } __attribute__ ((aligned (sizeof(uint64_t)))); |
| 272 | 306 | ||
| @@ -274,6 +308,7 @@ enum iscsi_param_type { | |||
| 274 | ISCSI_PARAM, /* iscsi_param (session, conn, target, LU) */ | 308 | ISCSI_PARAM, /* iscsi_param (session, conn, target, LU) */ |
| 275 | ISCSI_HOST_PARAM, /* iscsi_host_param */ | 309 | ISCSI_HOST_PARAM, /* iscsi_host_param */ |
| 276 | ISCSI_NET_PARAM, /* iscsi_net_param */ | 310 | ISCSI_NET_PARAM, /* iscsi_net_param */ |
| 311 | ISCSI_FLASHNODE_PARAM, /* iscsi_flashnode_param */ | ||
| 277 | }; | 312 | }; |
| 278 | 313 | ||
| 279 | struct iscsi_iface_param_info { | 314 | struct iscsi_iface_param_info { |
| @@ -469,6 +504,84 @@ enum iscsi_host_param { | |||
| 469 | ISCSI_HOST_PARAM_MAX, | 504 | ISCSI_HOST_PARAM_MAX, |
| 470 | }; | 505 | }; |
| 471 | 506 | ||
| 507 | /* iSCSI Flash Target params */ | ||
| 508 | enum iscsi_flashnode_param { | ||
| 509 | ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6, | ||
| 510 | ISCSI_FLASHNODE_PORTAL_TYPE, | ||
| 511 | ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE, | ||
| 512 | ISCSI_FLASHNODE_DISCOVERY_SESS, | ||
| 513 | ISCSI_FLASHNODE_ENTRY_EN, | ||
| 514 | ISCSI_FLASHNODE_HDR_DGST_EN, | ||
| 515 | ISCSI_FLASHNODE_DATA_DGST_EN, | ||
| 516 | ISCSI_FLASHNODE_IMM_DATA_EN, | ||
| 517 | ISCSI_FLASHNODE_INITIAL_R2T_EN, | ||
| 518 | ISCSI_FLASHNODE_DATASEQ_INORDER, | ||
| 519 | ISCSI_FLASHNODE_PDU_INORDER, | ||
| 520 | ISCSI_FLASHNODE_CHAP_AUTH_EN, | ||
| 521 | ISCSI_FLASHNODE_SNACK_REQ_EN, | ||
| 522 | ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN, | ||
| 523 | ISCSI_FLASHNODE_BIDI_CHAP_EN, | ||
| 524 | /* make authentication for discovery sessions optional */ | ||
| 525 | ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL, | ||
| 526 | ISCSI_FLASHNODE_ERL, | ||
| 527 | ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT, | ||
| 528 | ISCSI_FLASHNODE_TCP_NAGLE_DISABLE, | ||
| 529 | ISCSI_FLASHNODE_TCP_WSF_DISABLE, | ||
| 530 | ISCSI_FLASHNODE_TCP_TIMER_SCALE, | ||
| 531 | ISCSI_FLASHNODE_TCP_TIMESTAMP_EN, | ||
| 532 | ISCSI_FLASHNODE_IP_FRAG_DISABLE, | ||
| 533 | ISCSI_FLASHNODE_MAX_RECV_DLENGTH, | ||
| 534 | ISCSI_FLASHNODE_MAX_XMIT_DLENGTH, | ||
| 535 | ISCSI_FLASHNODE_FIRST_BURST, | ||
| 536 | ISCSI_FLASHNODE_DEF_TIME2WAIT, | ||
| 537 | ISCSI_FLASHNODE_DEF_TIME2RETAIN, | ||
| 538 | ISCSI_FLASHNODE_MAX_R2T, | ||
| 539 | ISCSI_FLASHNODE_KEEPALIVE_TMO, | ||
| 540 | ISCSI_FLASHNODE_ISID, | ||
| 541 | ISCSI_FLASHNODE_TSID, | ||
| 542 | ISCSI_FLASHNODE_PORT, | ||
| 543 | ISCSI_FLASHNODE_MAX_BURST, | ||
| 544 | ISCSI_FLASHNODE_DEF_TASKMGMT_TMO, | ||
| 545 | ISCSI_FLASHNODE_IPADDR, | ||
| 546 | ISCSI_FLASHNODE_ALIAS, | ||
| 547 | ISCSI_FLASHNODE_REDIRECT_IPADDR, | ||
| 548 | ISCSI_FLASHNODE_MAX_SEGMENT_SIZE, | ||
| 549 | ISCSI_FLASHNODE_LOCAL_PORT, | ||
| 550 | ISCSI_FLASHNODE_IPV4_TOS, | ||
| 551 | ISCSI_FLASHNODE_IPV6_TC, | ||
| 552 | ISCSI_FLASHNODE_IPV6_FLOW_LABEL, | ||
| 553 | ISCSI_FLASHNODE_NAME, | ||
| 554 | ISCSI_FLASHNODE_TPGT, | ||
| 555 | ISCSI_FLASHNODE_LINK_LOCAL_IPV6, | ||
| 556 | ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX, | ||
| 557 | ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE, | ||
| 558 | ISCSI_FLASHNODE_TCP_XMIT_WSF, | ||
| 559 | ISCSI_FLASHNODE_TCP_RECV_WSF, | ||
| 560 | ISCSI_FLASHNODE_CHAP_IN_IDX, | ||
| 561 | ISCSI_FLASHNODE_CHAP_OUT_IDX, | ||
| 562 | ISCSI_FLASHNODE_USERNAME, | ||
| 563 | ISCSI_FLASHNODE_USERNAME_IN, | ||
| 564 | ISCSI_FLASHNODE_PASSWORD, | ||
| 565 | ISCSI_FLASHNODE_PASSWORD_IN, | ||
| 566 | ISCSI_FLASHNODE_STATSN, | ||
| 567 | ISCSI_FLASHNODE_EXP_STATSN, | ||
| 568 | ISCSI_FLASHNODE_IS_BOOT_TGT, | ||
| 569 | |||
| 570 | ISCSI_FLASHNODE_MAX, | ||
| 571 | }; | ||
| 572 | |||
| 573 | struct iscsi_flashnode_param_info { | ||
| 574 | uint32_t len; /* Actual length of the param */ | ||
| 575 | uint16_t param; /* iscsi param value */ | ||
| 576 | uint8_t value[0]; /* length sized value follows */ | ||
| 577 | } __packed; | ||
| 578 | |||
| 579 | enum iscsi_discovery_parent_type { | ||
| 580 | ISCSI_DISC_PARENT_UNKNOWN = 0x1, | ||
| 581 | ISCSI_DISC_PARENT_SENDTGT = 0x2, | ||
| 582 | ISCSI_DISC_PARENT_ISNS = 0x3, | ||
| 583 | }; | ||
| 584 | |||
| 472 | /* iSCSI port Speed */ | 585 | /* iSCSI port Speed */ |
| 473 | enum iscsi_port_speed { | 586 | enum iscsi_port_speed { |
| 474 | ISCSI_PORT_SPEED_UNKNOWN = 0x1, | 587 | ISCSI_PORT_SPEED_UNKNOWN = 0x1, |
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 53f0b361d668..4a58cca2ecc1 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h | |||
| @@ -39,6 +39,8 @@ struct iscsi_task; | |||
| 39 | struct sockaddr; | 39 | struct sockaddr; |
| 40 | struct iscsi_iface; | 40 | struct iscsi_iface; |
| 41 | struct bsg_job; | 41 | struct bsg_job; |
| 42 | struct iscsi_bus_flash_session; | ||
| 43 | struct iscsi_bus_flash_conn; | ||
| 42 | 44 | ||
| 43 | /** | 45 | /** |
| 44 | * struct iscsi_transport - iSCSI Transport template | 46 | * struct iscsi_transport - iSCSI Transport template |
| @@ -150,6 +152,19 @@ struct iscsi_transport { | |||
| 150 | int (*get_chap) (struct Scsi_Host *shost, uint16_t chap_tbl_idx, | 152 | int (*get_chap) (struct Scsi_Host *shost, uint16_t chap_tbl_idx, |
| 151 | uint32_t *num_entries, char *buf); | 153 | uint32_t *num_entries, char *buf); |
| 152 | int (*delete_chap) (struct Scsi_Host *shost, uint16_t chap_tbl_idx); | 154 | int (*delete_chap) (struct Scsi_Host *shost, uint16_t chap_tbl_idx); |
| 155 | int (*get_flashnode_param) (struct iscsi_bus_flash_session *fnode_sess, | ||
| 156 | int param, char *buf); | ||
| 157 | int (*set_flashnode_param) (struct iscsi_bus_flash_session *fnode_sess, | ||
| 158 | struct iscsi_bus_flash_conn *fnode_conn, | ||
| 159 | void *data, int len); | ||
| 160 | int (*new_flashnode) (struct Scsi_Host *shost, const char *buf, | ||
| 161 | int len); | ||
| 162 | int (*del_flashnode) (struct iscsi_bus_flash_session *fnode_sess); | ||
| 163 | int (*login_flashnode) (struct iscsi_bus_flash_session *fnode_sess, | ||
| 164 | struct iscsi_bus_flash_conn *fnode_conn); | ||
| 165 | int (*logout_flashnode) (struct iscsi_bus_flash_session *fnode_sess, | ||
| 166 | struct iscsi_bus_flash_conn *fnode_conn); | ||
| 167 | int (*logout_flashnode_sid) (struct iscsi_cls_session *cls_sess); | ||
| 153 | }; | 168 | }; |
| 154 | 169 | ||
| 155 | /* | 170 | /* |
| @@ -286,6 +301,112 @@ struct iscsi_iface { | |||
| 286 | #define iscsi_iface_to_shost(_iface) \ | 301 | #define iscsi_iface_to_shost(_iface) \ |
| 287 | dev_to_shost(_iface->dev.parent) | 302 | dev_to_shost(_iface->dev.parent) |
| 288 | 303 | ||
| 304 | |||
| 305 | struct iscsi_bus_flash_conn { | ||
| 306 | struct list_head conn_list; /* item in connlist */ | ||
| 307 | void *dd_data; /* LLD private data */ | ||
| 308 | struct iscsi_transport *transport; | ||
| 309 | struct device dev; /* sysfs transport/container device */ | ||
| 310 | /* iscsi connection parameters */ | ||
| 311 | uint32_t exp_statsn; | ||
| 312 | uint32_t statsn; | ||
| 313 | unsigned max_recv_dlength; /* initiator_max_recv_dsl*/ | ||
| 314 | unsigned max_xmit_dlength; /* target_max_recv_dsl */ | ||
| 315 | unsigned max_segment_size; | ||
| 316 | unsigned tcp_xmit_wsf; | ||
| 317 | unsigned tcp_recv_wsf; | ||
| 318 | int hdrdgst_en; | ||
| 319 | int datadgst_en; | ||
| 320 | int port; | ||
| 321 | char *ipaddress; | ||
| 322 | char *link_local_ipv6_addr; | ||
| 323 | char *redirect_ipaddr; | ||
| 324 | uint16_t keepalive_timeout; | ||
| 325 | uint16_t local_port; | ||
| 326 | uint8_t snack_req_en; | ||
| 327 | /* tcp timestamp negotiation status */ | ||
| 328 | uint8_t tcp_timestamp_stat; | ||
| 329 | uint8_t tcp_nagle_disable; | ||
| 330 | /* tcp window scale factor */ | ||
| 331 | uint8_t tcp_wsf_disable; | ||
| 332 | uint8_t tcp_timer_scale; | ||
| 333 | uint8_t tcp_timestamp_en; | ||
| 334 | uint8_t ipv4_tos; | ||
| 335 | uint8_t ipv6_traffic_class; | ||
| 336 | uint8_t ipv6_flow_label; | ||
| 337 | uint8_t fragment_disable; | ||
| 338 | /* Link local IPv6 address is assigned by firmware or driver */ | ||
| 339 | uint8_t is_fw_assigned_ipv6; | ||
| 340 | }; | ||
| 341 | |||
| 342 | #define iscsi_dev_to_flash_conn(_dev) \ | ||
| 343 | container_of(_dev, struct iscsi_bus_flash_conn, dev) | ||
| 344 | |||
| 345 | #define iscsi_flash_conn_to_flash_session(_conn) \ | ||
| 346 | iscsi_dev_to_flash_session(_conn->dev.parent) | ||
| 347 | |||
| 348 | #define ISID_SIZE 6 | ||
| 349 | |||
| 350 | struct iscsi_bus_flash_session { | ||
| 351 | struct list_head sess_list; /* item in session_list */ | ||
| 352 | struct iscsi_transport *transport; | ||
| 353 | unsigned int target_id; | ||
| 354 | int flash_state; /* persistent or non-persistent */ | ||
| 355 | void *dd_data; /* LLD private data */ | ||
| 356 | struct device dev; /* sysfs transport/container device */ | ||
| 357 | /* iscsi session parameters */ | ||
| 358 | unsigned first_burst; | ||
| 359 | unsigned max_burst; | ||
| 360 | unsigned short max_r2t; | ||
| 361 | int default_taskmgmt_timeout; | ||
| 362 | int initial_r2t_en; | ||
| 363 | int imm_data_en; | ||
| 364 | int time2wait; | ||
| 365 | int time2retain; | ||
| 366 | int pdu_inorder_en; | ||
| 367 | int dataseq_inorder_en; | ||
| 368 | int erl; | ||
| 369 | int tpgt; | ||
| 370 | char *username; | ||
| 371 | char *username_in; | ||
| 372 | char *password; | ||
| 373 | char *password_in; | ||
| 374 | char *targetname; | ||
| 375 | char *targetalias; | ||
| 376 | char *portal_type; | ||
| 377 | uint16_t tsid; | ||
| 378 | uint16_t chap_in_idx; | ||
| 379 | uint16_t chap_out_idx; | ||
| 380 | /* index of iSCSI discovery session if the entry is | ||
| 381 | * discovered by iSCSI discovery session | ||
| 382 | */ | ||
| 383 | uint16_t discovery_parent_idx; | ||
| 384 | /* indicates if discovery was done through iSNS discovery service | ||
| 385 | * or through sendTarget */ | ||
| 386 | uint16_t discovery_parent_type; | ||
| 387 | /* Firmware auto sendtarget discovery disable */ | ||
| 388 | uint8_t auto_snd_tgt_disable; | ||
| 389 | uint8_t discovery_sess; | ||
| 390 | /* indicates if this flashnode entry is enabled or disabled */ | ||
| 391 | uint8_t entry_state; | ||
| 392 | uint8_t chap_auth_en; | ||
| 393 | /* enables firmware to auto logout the discovery session on discovery | ||
| 394 | * completion | ||
| 395 | */ | ||
| 396 | uint8_t discovery_logout_en; | ||
| 397 | uint8_t bidi_chap_en; | ||
| 398 | /* makes authentication for discovery session optional */ | ||
| 399 | uint8_t discovery_auth_optional; | ||
| 400 | uint8_t isid[ISID_SIZE]; | ||
| 401 | uint8_t is_boot_target; | ||
| 402 | }; | ||
| 403 | |||
| 404 | #define iscsi_dev_to_flash_session(_dev) \ | ||
| 405 | container_of(_dev, struct iscsi_bus_flash_session, dev) | ||
| 406 | |||
| 407 | #define iscsi_flash_session_to_shost(_session) \ | ||
| 408 | dev_to_shost(_session->dev.parent) | ||
| 409 | |||
| 289 | /* | 410 | /* |
| 290 | * session and connection functions that can be used by HW iSCSI LLDs | 411 | * session and connection functions that can be used by HW iSCSI LLDs |
| 291 | */ | 412 | */ |
| @@ -330,4 +451,34 @@ extern char *iscsi_get_port_speed_name(struct Scsi_Host *shost); | |||
| 330 | extern char *iscsi_get_port_state_name(struct Scsi_Host *shost); | 451 | extern char *iscsi_get_port_state_name(struct Scsi_Host *shost); |
| 331 | extern int iscsi_is_session_dev(const struct device *dev); | 452 | extern int iscsi_is_session_dev(const struct device *dev); |
| 332 | 453 | ||
| 454 | extern char *iscsi_get_discovery_parent_name(int parent_type); | ||
| 455 | extern struct device * | ||
| 456 | iscsi_find_flashnode(struct Scsi_Host *shost, void *data, | ||
| 457 | int (*fn)(struct device *dev, void *data)); | ||
| 458 | |||
| 459 | extern struct iscsi_bus_flash_session * | ||
| 460 | iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index, | ||
| 461 | struct iscsi_transport *transport, int dd_size); | ||
| 462 | |||
| 463 | extern struct iscsi_bus_flash_conn * | ||
| 464 | iscsi_create_flashnode_conn(struct Scsi_Host *shost, | ||
| 465 | struct iscsi_bus_flash_session *fnode_sess, | ||
| 466 | struct iscsi_transport *transport, int dd_size); | ||
| 467 | |||
| 468 | extern void | ||
| 469 | iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess); | ||
| 470 | |||
| 471 | extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost); | ||
| 472 | extern int iscsi_flashnode_bus_match(struct device *dev, | ||
| 473 | struct device_driver *drv); | ||
| 474 | extern int iscsi_is_flashnode_conn_dev(struct device *dev, void *data); | ||
| 475 | |||
| 476 | extern struct device * | ||
| 477 | iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data, | ||
| 478 | int (*fn)(struct device *dev, void *data)); | ||
| 479 | |||
| 480 | extern struct device * | ||
| 481 | iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess, | ||
| 482 | void *data, | ||
| 483 | int (*fn)(struct device *dev, void *data)); | ||
| 333 | #endif | 484 | #endif |
