diff options
author | Adheer Chandravanshi <adheer.chandravanshi@qlogic.com> | 2013-03-22 07:41:29 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-04-11 18:19:35 -0400 |
commit | c6a4bb2ef596d0bfe0d885ef6807b263ac83e47a (patch) | |
tree | 317560eb93ab800b72a8a33762a1228b3dc40e94 | |
parent | 9060f6bfc389edb195548d7357e588430c32ab77 (diff) |
[SCSI] scsi_transport_iscsi: Add flash node mgmt support
This patch allows iscsiadm to manage iSCSI target information stored on
adapter flash on per host basis.
The sysfs entries will look as cited below:
/sys/bus/iscsi_flashnode/devices/flashnode_sess-<host_no>:<flashnode_id>/<session attrs>
/sys/bus/iscsi_flashnode/devices/flashnode_conn-<host_no>:<flashnode_id>:<conn_id>/<conn attrs>
Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com>
Signed-off-by: Manish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-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 |